'use client';

import { type ReactNode } from 'react';
import { cn } from '@/lib/utils';
import { AIStamp, Chip, MD, tone } from './shared';
import { ChainDetailView } from './chain-viz';
import { EmrSoapView } from './emr-soap-view';
import { FactsTimeline } from './facts-timeline';
import { cleanPersonaValue } from './persona-display';
import { PersonaFeatureHover } from './persona-feature-hover';
import type { Chain, PersonaFeature, PlanReason } from './mock-data';
import type { AdaptedFact } from './adapt-data';

export type DrawerKind = 'chain-detail' | 'medical' | 'image' | 'facts' | 'persona' | null;

export function Drawer({
  open,
  onClose,
  kind,
  chains,
  persona,
  summaries,
  reason,
  facts,
  fmtRel,
  summaryOverride,
  summaryStreaming,
  onRegenerateSummary,
}: {
  open: boolean;
  onClose: () => void;
  kind: DrawerKind;
  chains: Chain[];
  persona: { computedAt: Date; features: PersonaFeature[] };
  summaries: {
    medical_record: { content: string; generatedAt: Date };
    treatment_chain: { content: string; generatedAt: Date };
  };
  reason: PlanReason;
  /// v2.1:所有 active fact(FactsTimeline + ImageDrawer 用)
  facts: AdaptedFact[];
  fmtRel: (d: Date) => string;
  /** AI 流式重生成结果(部分或完成);存在时覆盖 mock summaries 显示 */
  summaryOverride?: {
    medicalRecord?: string;
    treatmentChain?: string;
  };
  /** 是否正在流式生成中(显示 "AI 正在生成" 指示) */
  summaryStreaming?: boolean;
  /** 触发重新生成(plan-detail-app 传入,绑了 planId) */
  onRegenerateSummary?: () => void;
}) {
  if (!open || !kind) return null;

  const medicalText = summaryOverride?.medicalRecord ?? summaries.medical_record.content;
  const chainText = summaryOverride?.treatmentChain ?? summaries.treatment_chain.content;

  let title = '';
  let subtitle = '';
  let body: ReactNode = null;
  let width = 'w-[540px]';

  if (kind === 'chain-detail') {
    title = '治疗链全景';
    subtitle = `${chains.length} 条治疗链 · 含本次召回目标 + 历史信任锚`;
    // AI 跨链叙述移除 — 5 阶段 timeline 已表达全部事实(具体动作 / 关键事实 / 医生 / 时间 / 建议下一步),
    // AI 文本再叠加是冗余;后续若客服真有"自然语言摘要"需求,可在病历快读里加而非这里。
    body = <ChainDetailView chains={chains} />;
    width = 'w-[760px]';
  } else if (kind === 'medical') {
    // 病历快读改为 PAC 事实驱动 + SOAP 结构化展示(W3 末从 AI 文本改造)
    // 数据源:emr_record + 同 source_encounter 的 diagnosis_record / treatment_record / image_record
    const emrCount = facts.filter((f) => f.type === 'emr_record').length;
    title = '病历快读';
    subtitle = `${emrCount} 次接诊病历`;
    body = <EmrSoapView facts={facts} />;
    width = 'w-[700px]';
  } else if (kind === 'image') {
    const imageFacts = facts.filter((f) => f.type === 'image_record');
    title = `影像资料(${imageFacts.length})`;
    subtitle = imageFacts.length > 0
      ? `最早 ${imageFacts[imageFacts.length - 1]?.occurredAt?.slice(0, 10) ?? '—'} ~ 最近 ${imageFacts[0]?.occurredAt?.slice(0, 10) ?? '—'}`
      : '无影像 fact';
    body = <ImageFactsView facts={imageFacts} />;
    width = 'w-[640px]';
  } else if (kind === 'facts') {
    title = `患者事实时间轴(${facts.length})`;
    subtitle = '按时间倒序';
    body = <FactsTimeline facts={facts} />;
    width = 'w-[640px]';
  } else if (kind === 'persona') {
    title = '患者画像';
    subtitle = `更新于 ${fmtRel(persona.computedAt)} · ${persona.features.length} 项画像`;
    body = (
      <div className="space-y-3">
        <AIStamp relative={fmtRel(persona.computedAt)} label="画像重算" />
        {persona.features.map((f) => {
          const T = tone(f.tone);
          const { tag, text } = cleanPersonaValue(f.value);
          return (
            <div key={f.key} className="relative rounded-md border border-slate-200 p-3">
              {/* 右上角 ? hover 看算法说明 */}
              <PersonaFeatureHover featureKey={f.key}>
                <span
                  className="absolute top-2 right-2 inline-flex items-center justify-center w-4 h-4 rounded-full text-slate-400 cursor-help hover:text-slate-700 hover:bg-slate-100"
                  aria-label="查看算法说明"
                >
                  <svg viewBox="0 0 24 24" className="w-3 h-3" fill="none" stroke="currentColor" strokeWidth="2">
                    <circle cx="12" cy="12" r="10" />
                    <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3M12 17h.01" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                </span>
              </PersonaFeatureHover>
              <div className={cn('inline-flex items-center gap-1.5 text-[11px] font-semibold', T.text)}>
                <span className={cn('w-1.5 h-1.5 rounded-full', T.dot)} />
                {f.label}
                {tag && (
                  <span className="ml-1 px-1 py-0 rounded bg-slate-100 text-slate-600 text-[10.5px] font-normal">
                    {tag}
                  </span>
                )}
              </div>
              {text && <div className="text-[13px] font-medium text-slate-900 mt-1">{text}</div>}
            </div>
          );
        })}
      </div>
    );
  }

  return (
    <div className="fixed inset-0 z-40 flex" onClick={onClose}>
      <div className="flex-1 bg-slate-900/30" />
      <aside
        className={cn('max-w-[92vw] bg-white shadow-2xl border-l border-slate-200 flex flex-col', width)}
        onClick={(e) => e.stopPropagation()}
      >
        <header className="px-5 py-3.5 border-b border-slate-100 flex items-center justify-between flex-none">
          <div>
            <h3 className="text-[14px] font-semibold text-slate-900">{title}</h3>
            <p className="text-[11px] text-slate-500 mt-0.5">{subtitle}</p>
          </div>
          <button
            onClick={onClose}
            className="w-7 h-7 rounded-md hover:bg-slate-100 flex items-center justify-center text-slate-500"
          >
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="w-4 h-4">
              <path d="M6 6l12 12M18 6L6 18" strokeLinecap="round" />
            </svg>
          </button>
        </header>
        <div className="flex-1 overflow-y-auto p-5">{body}</div>
      </aside>
    </div>
  );
}

// ──────────────────────────────────────────
// 重新生成摘要按钮 + 流式中提示
// ──────────────────────────────────────────
function RegenSummaryBtn({
  streaming,
  onClick,
}: {
  streaming: boolean;
  onClick?: () => void;
}) {
  if (!onClick) return null;
  return (
    <button
      onClick={onClick}
      disabled={streaming}
      title={streaming ? 'AI 正在生成中…' : '重新生成此摘要(同时刷新另外 2 段)'}
      className={cn(
        'inline-flex items-center gap-1 px-2 py-0.5 rounded text-[10.5px] transition-colors',
        streaming
          ? 'text-slate-400 bg-slate-100 cursor-not-allowed'
          : 'text-slate-500 hover:text-indigo-700 hover:bg-indigo-50',
      )}
    >
      <svg
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.8"
        strokeLinecap="round"
        strokeLinejoin="round"
        className={cn('w-3 h-3', streaming && 'animate-spin')}
      >
        <path d="M23 4v6h-6M1 20v-6h6" />
        <path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" />
      </svg>
      {streaming ? 'AI 生成中' : '重新生成'}
    </button>
  );
}

function StreamingHint() {
  return (
    <div className="text-[11px] text-indigo-600 font-mono mb-2 inline-flex items-center gap-1">
      <span className="inline-flex items-center gap-[2px]">
        <span className="w-1 h-1 rounded-full bg-indigo-500 animate-[pulse_1.2s_ease-in-out_infinite]" />
        <span className="w-1 h-1 rounded-full bg-indigo-500 animate-[pulse_1.2s_ease-in-out_0.2s_infinite]" />
        <span className="w-1 h-1 rounded-full bg-indigo-500 animate-[pulse_1.2s_ease-in-out_0.4s_infinite]" />
      </span>
      AI 正在生成 · 流式输出中
    </div>
  );
}

// ──────────────────────────────────────────
// ImageFactsView — image_record fact 列表(真实数据)
// 影像原图走宿主系统(actionUrls.VIEW_IMAGE);此处只展示 metadata + finding
// ──────────────────────────────────────────
function ImageFactsView({ facts }: { facts: AdaptedFact[] }) {
  if (facts.length === 0) {
    return (
      <div className="text-center py-12 text-sm text-slate-400">
        无影像 fact
        <div className="text-[10.5px] mt-1.5">
          (DW 给的是 metadata + URL,原图走宿主影像系统跳转)
        </div>
      </div>
    );
  }
  return (
    <div className="space-y-2.5">
      {facts.map((f) => {
        const c = (f.content ?? {}) as Record<string, unknown>;
        const modality = (c.modality as string | undefined) ?? 'image';
        const finding = (c.finding as string | undefined) ?? null;
        const tooths = Array.isArray(c.tooth_positions)
          ? (c.tooth_positions as string[]).join(' / ')
          : ((c.tooth_position as string | undefined) ?? null);
        const encId = c.encounter_external_id as string | undefined;
        return (
          <div key={f.id} className="rounded-md border border-slate-200 p-3">
            <div className="flex items-center justify-between mb-1.5">
              <div className="flex items-center gap-2">
                <Chip tone="violet" size="xs">
                  {modality.toUpperCase()}
                </Chip>
                {tooths && (
                  <span className="text-[11px] text-slate-600 font-mono tabular-nums">
                    牙位 {tooths}
                  </span>
                )}
              </div>
              <span className="text-[10.5px] text-slate-400 tabular-nums font-mono">
                {f.occurredAt?.slice(0, 10) ?? '—'}
              </span>
            </div>
            {finding ? (
              <div className="text-[12px] text-slate-700 leading-relaxed">{finding}</div>
            ) : (
              <div className="text-[11px] text-slate-400 italic">(无 finding 备注)</div>
            )}
            {encId && (
              <div className="mt-1.5 text-[10px] text-slate-400 font-mono">
                source encounter: {encId}
              </div>
            )}
          </div>
        );
      })}
      <div className="text-[10.5px] text-slate-400 pt-2 border-t border-slate-100">
        如需查看原始 DICOM,请跳转宿主影像系统(deep-link 待 host actionUrls 接入)
      </div>
    </div>
  );
}

// ──────────────────────────────────────────
// CBCT Image View(mock placeholder)— deprecated,留作 fallback
// ──────────────────────────────────────────
function CBCTImageView() {
  return (
    <div className="space-y-3">
      <div className="aspect-[4/3] rounded-lg border border-slate-200 bg-slate-900 relative overflow-hidden">
        <div
          className="absolute inset-0"
          style={{ backgroundImage: 'radial-gradient(circle at 50% 60%, #475569 0%, #0f172a 50%, #000 100%)' }}
        />
        <svg viewBox="0 0 400 300" className="absolute inset-0 w-full h-full opacity-70">
          <path d="M80 180 Q200 80 320 180" stroke="#64748b" strokeWidth="2" fill="none" opacity="0.6" />
          {[100, 130, 160, 190, 220, 250, 280, 300].map((x, i) => (
            <rect
              key={i}
              x={x}
              y={150 + Math.abs(i - 4) * 8}
              width="18"
              height="32"
              rx="3"
              fill="#94a3b8"
              opacity="0.7"
            />
          ))}
          <rect x="139" y="170" width="18" height="32" rx="3" fill="none" stroke="#f43f5e" strokeWidth="2" strokeDasharray="4 3" />
          <line x1="148" y1="170" x2="148" y2="130" stroke="#f43f5e" strokeWidth="1.5" />
          <circle cx="148" cy="125" r="3" fill="#f43f5e" />
        </svg>
        <div className="absolute top-3 left-3 px-2 py-1 rounded bg-black/60 text-white text-[10px] font-mono">
          CBCT · 36 区骨量评估
        </div>
        <div className="absolute top-3 right-3 px-2 py-1 rounded bg-rose-600 text-white text-[10px] font-medium">
          医生标注 · 牙缺失
        </div>
        <div className="absolute bottom-3 left-3 text-white/70 text-[10px] font-mono">
          2025.12.10 · 医生 李**军
        </div>
        <div className="absolute bottom-3 right-3 text-white/70 text-[10px] font-mono tabular-nums">骨量 11.2mm</div>
      </div>
      <div className="text-[11.5px] text-slate-500 leading-relaxed">
        如需重新加载原始 DICOM,请跳转宿主影像系统。诊断结论与医嘱详见「病历快读」。
      </div>
    </div>
  );
}

