'use client';

import { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import type { AssetPack, AssetTemplate, GenImage, GenSession, PackKind, ToyAsset } from '@/lib/types';
import { PACK_LABELS, PACK_ORDER, PACK_TEMPLATES, TEXT_TEMPLATES, VIDEO_TEMPLATES } from '@/lib/templates';
import { HoverImagePreview, HoverVideoPreview } from './HoverImagePreview';

const PACK_DESCRIPTIONS: Record<PackKind, string> = {
  patent: '六面视图 · 45° 立体图 · 局部放大',
  accessories: '配件六视图 · 连接结构 · 尺寸 · 组合图',
  production: '尺寸 · 材料 · 颜色 · 拆件 · 包装',
  marketing: '白底商品图 · 场景图 · 细节图 · 社媒图',
};

const PACK_ACCENT: Record<PackKind, { bar: string; chip: string; icon: string }> = {
  patent: { bar: 'from-[#e6f578] to-[#d6b36a]', chip: 'bg-[#e6f578]/15 text-[#e6f578] border-[#e6f578]/30', icon: 'P' },
  accessories: { bar: 'from-[#8cb478] to-[#547a43]', chip: 'bg-[#8cb478]/15 text-[#cfe7a7] border-[#8cb478]/30', icon: 'A' },
  production: { bar: 'from-[#d6b36a] to-[#b6813c]', chip: 'bg-[#d6b36a]/15 text-[#f2d38c] border-[#d6b36a]/30', icon: 'F' },
  marketing: { bar: 'from-[#b6df72] to-[#4f9a56]', chip: 'bg-[#b6df72]/15 text-[#dff5a8] border-[#b6df72]/30', icon: 'M' },
};

const ASPECT_PX: Record<AssetTemplate['aspectRatio'], string> = {
  '1:1': '1024×1024',
  '3:4': '1024×1365',
  '4:5': '1024×1280',
  '9:16': '1080×1920',
  '16:9': '1920×1080',
  'long': '1024×3200',
};

function aspectCss(aspectRatio: AssetTemplate['aspectRatio'] | string | undefined): string {
  if (!aspectRatio) return '1 / 1';
  if (aspectRatio === 'long') return '1 / 3';
  return aspectRatio.replace(':', ' / ');
}

type AssetDetail = {
  template: AssetTemplate;
  asset: ToyAsset | undefined;
};

function formatDate(timestamp?: number) {
  if (!timestamp) return '未生成';
  return new Date(timestamp).toLocaleString('zh-CN');
}

function AssetTile({ template, asset, onOpen }: {
  template: AssetTemplate;
  asset: ToyAsset | undefined;
  onOpen: () => void;
}) {
  const ready = !!asset;

  return (
    <button
      type="button"
      onClick={onOpen}
      className={`asset-tile ${ready ? 'asset-tile--ready' : ''}`}
      title={ready ? `查看${template.title}详情` : `查看${template.title}要求`}
    >
      <div className="asset-tile__thumb" style={{ aspectRatio: aspectCss(asset?.aspectRatio ?? template.aspectRatio) }}>
        {ready ? (
          <HoverImagePreview
            src={asset!.url}
            alt={template.title}
            aspectRatio={asset!.aspectRatio}
            imageClassName="h-full w-full rounded-[8px] bg-white object-contain"
          />
        ) : (
          <div className="grid h-full w-full place-items-center rounded-[8px] bg-black/28">
            <span className="font-mono text-[10px] text-white/32">{template.aspectRatio}</span>
          </div>
        )}
        <span className={`asset-tile__state ${ready ? 'asset-tile__state--done' : ''}`}>
          {ready ? '✓' : '待'}
        </span>
      </div>
      <div className="asset-tile__body">
        <div className="flex min-w-0 items-center gap-1.5">
          <span className="truncate text-[12px] font-semibold text-white">{template.title}</span>
          {template.required && <span className="shrink-0 text-[9px] text-[#e6f578]/75">必备</span>}
        </div>
        <p className="mt-1 line-clamp-2 text-left text-[10px] leading-relaxed text-white/42">{template.description}</p>
        <div className="mt-auto flex items-center justify-between gap-2 pt-2">
          <span className="font-mono text-[9px] text-white/34">{ASPECT_PX[template.aspectRatio]}</span>
          <span className={`font-mono text-[10px] ${ready ? 'text-[#dff5a8]' : 'text-white/28'}`}>
            {ready ? `L${asset!.derivationLevel}` : 'EMPTY'}
          </span>
        </div>
      </div>
    </button>
  );
}

function AssetDetailDrawer({ detail, onClose }: {
  detail: AssetDetail | null;
  onClose: () => void;
}) {
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);
  }, []);

  useEffect(() => {
    if (!detail) return;
    function handleKey(event: KeyboardEvent) {
      if (event.key === 'Escape') onClose();
    }
    window.addEventListener('keydown', handleKey);
    return () => window.removeEventListener('keydown', handleKey);
  }, [detail, onClose]);

  if (!mounted) return null;

  const template = detail?.template;
  const asset = detail?.asset;
  const ready = !!asset;
  const drawer = (
    <>
      <div className={`asset-detail-backdrop ${detail ? 'is-open' : ''}`} onClick={onClose} />
      <aside className={`asset-detail-drawer ${detail ? 'is-open' : ''}`} aria-hidden={!detail}>
        {template && (
          <>
            <div className="flex shrink-0 items-start justify-between gap-4 border-b border-white/10 p-5">
              <div className="min-w-0">
                <span className="section-eyebrow">Asset Detail</span>
                <h2 className="mt-2 text-lg font-semibold text-white">{template.title}</h2>
                <p className="mt-1 text-xs leading-relaxed text-white/44">{template.description}</p>
              </div>
              <button
                type="button"
                onClick={onClose}
                className="grid h-10 w-10 shrink-0 place-items-center rounded-[8px] bg-white/[0.06] text-white/60 ring-1 ring-white/10 transition-colors hover:bg-white/[0.10] hover:text-white"
                title="关闭详情"
                aria-label="关闭详情"
              >
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" aria-hidden="true">
                  <path d="M6 6l12 12M18 6 6 18" strokeLinecap="round" />
                </svg>
              </button>
            </div>

            <div className="min-h-0 flex-1 overflow-y-auto p-5">
              <div className="asset-detail-image" style={{ aspectRatio: aspectCss(asset?.aspectRatio ?? template.aspectRatio) }}>
                {ready ? (
                  <img src={asset.url} alt={template.title} />
                ) : (
                  <div className="grid h-full w-full place-items-center text-sm text-white/36">待生成</div>
                )}
              </div>

              <div className="mt-4 grid grid-cols-2 gap-2 text-[11px]">
                <DetailItem label="状态" value={ready ? asset.status : '待生成'} />
                <DetailItem label="尺寸" value={ASPECT_PX[template.aspectRatio]} />
                <DetailItem label="比例" value={asset?.aspectRatio ?? template.aspectRatio} />
                <DetailItem label="层级" value={ready ? `L${asset.derivationLevel}` : '-'} />
                <DetailItem label="视图" value={asset?.view ?? template.view} />
                <DetailItem label="创建" value={formatDate(asset?.createdAt)} />
                <DetailItem label="模板" value={template.id} />
                <DetailItem label="版本" value={asset?.version ?? '-'} />
              </div>

              {(asset?.anchorAssetId || asset?.anchorImageUrl) && (
                <div className="asset-detail-block">
                  <div className="asset-detail-label">Anchor</div>
                  <div className="asset-detail-code">{asset.anchorAssetId ?? asset.anchorImageUrl}</div>
                </div>
              )}

              <div className="asset-detail-block">
                <div className="asset-detail-label">Prompt</div>
                <pre className="asset-detail-pre">{asset?.prompt ?? template.promptTemplate}</pre>
              </div>

              {template.checklist.length > 0 && (
                <div className="asset-detail-block">
                  <div className="asset-detail-label">检查点</div>
                  <div className="space-y-1.5">
                    {template.checklist.map(item => (
                      <div key={item} className="flex gap-2 text-[11px] leading-relaxed text-white/62">
                        <span className="mt-[7px] h-1 w-1 shrink-0 rounded-full bg-[#e6f578]/70" />
                        <span>{item}</span>
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </div>
          </>
        )}
      </aside>
    </>
  );

  return createPortal(drawer, document.body);
}

function DetailItem({ label, value }: { label: string; value: string | number }) {
  return (
    <div className="rounded-[8px] bg-white/[0.035] p-3 ring-1 ring-white/[0.07]">
      <div className="text-[10px] text-white/34">{label}</div>
      <div className="mt-1 truncate text-[12px] text-white/76">{value}</div>
    </div>
  );
}

/* ── Pack Section ─────────────────────────────── */
function PackSection({ kind, pack, locked, lockReason, stepIndex }: {
  kind: PackKind;
  pack: AssetPack | undefined;
  locked: boolean;
  lockReason?: string;
  stepIndex: number;
}) {
  const [detail, setDetail] = useState<AssetDetail | null>(null);
  const accent = PACK_ACCENT[kind];
  const templates = PACK_TEMPLATES[kind];
  const generatedCount = pack?.assets.length ?? 0;
  const total = templates.length;
  const complete = generatedCount >= total;

  return (
    <section className={`card ${locked ? 'opacity-55' : ''}`} id={`pack-${kind}`} aria-disabled={locked}>
      <div className="flex items-center gap-3 px-4 py-3">
        <div className={`w-8 h-8 rounded-lg ${locked ? 'bg-white/[0.06] text-white/28' : `bg-gradient-to-br ${accent.bar} text-white`} flex items-center justify-center text-[11px] font-bold shrink-0`}>
          {stepIndex}
        </div>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 flex-wrap">
            <span className="text-sm font-semibold text-white">{PACK_LABELS[kind]}明细</span>
            <span className="text-[10px] text-white/35">{PACK_DESCRIPTIONS[kind]}</span>
            {complete && <span className="chip chip-live text-[10px] py-0">完成</span>}
            {locked && <span className="chip chip-neutral text-[10px] py-0">锁定</span>}
          </div>
        </div>
        <span className="shrink-0 font-mono text-[10px] text-white/35">{generatedCount}/{total}</span>
      </div>

      {locked && lockReason && (
        <div className="mx-4 mb-4 rounded-[8px] border border-white/[0.06] bg-black/20 px-3 py-2 text-[11px] text-white/38">
          {lockReason}
        </div>
      )}

      <div className="border-t border-white/[0.05] px-4 pb-4">
        <div className="asset-strip pt-3">
          {templates.map(template => {
            const asset = pack?.assets.find(a => a.templateId === template.id);
            return (
              <AssetTile
                key={template.id}
                template={template}
                asset={asset}
                onOpen={() => setDetail({ template, asset })}
              />
            );
          })}
        </div>
      </div>
      <AssetDetailDrawer detail={detail} onClose={() => setDetail(null)} />
    </section>
  );
}

/* ── Text Template Section ────────────────────── */
function TextTemplateSection({
  locked,
  session,
  loading,
  onGenerateText,
}: {
  locked: boolean;
  session: GenSession;
  loading: boolean;
  onGenerateText: () => void;
}) {
  const [showPromptId, setShowPromptId] = useState<string | null>(null);
  const textAssets = session.textAssets ?? [];
  const byTemplate = new Map(textAssets.map(asset => [asset.templateId, asset]));
  const completeCount = TEXT_TEMPLATES.filter(template => byTemplate.has(template.id)).length;

  return (
    <section className={`card overflow-hidden ${locked ? 'opacity-60' : ''}`} id="pack-text" aria-disabled={locked}>
      <div className="p-4 flex items-center gap-3">
        <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-[#8cb478] to-[#d6b36a] flex items-center justify-center text-white text-[11px] font-bold shrink-0">T</div>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <span className="text-sm font-semibold text-white">设计说明文字</span>
            <span className="text-[10px] text-white/35">专利说明 · 工厂说明 · 宣发文案 · 视频脚本</span>
          </div>
          <div className="mt-2 flex items-center gap-2">
            <div className="flex-1 h-1 rounded-full bg-white/[0.06] overflow-hidden">
              <div className="h-full bg-gradient-to-r from-[#8cb478] to-[#d6b36a]" style={{ width: `${Math.round((completeCount / TEXT_TEMPLATES.length) * 100)}%` }} />
            </div>
            <span className="text-[10px] font-mono text-white/35 shrink-0">{completeCount}/{TEXT_TEMPLATES.length}</span>
          </div>
        </div>
        <div className="flex items-center gap-2 shrink-0">
          <span className="chip bg-[#8cb478]/15 text-[#cfe7a7] border-[#8cb478]/30 text-[10px]">GPT Text</span>
          <button
            type="button"
            onClick={onGenerateText}
            disabled={locked || loading}
            className="btn btn-primary px-3 py-1.5 text-[11px] disabled:opacity-40"
          >
            {loading ? '生成中' : completeCount ? '刷新文字' : '生成文字'}
          </button>
        </div>
      </div>

      <div className="grid grid-cols-1 gap-3 border-t border-white/[0.05] p-4 lg:grid-cols-2 2xl:grid-cols-3">
        {TEXT_TEMPLATES.map(template => {
          const isOpen = showPromptId === template.id;
          const asset = byTemplate.get(template.id);
          return (
            <div key={template.id} className="flex min-h-[240px] min-w-0 flex-col rounded-[8px] bg-white/[0.025] p-3 ring-1 ring-white/[0.05] transition-all hover:ring-white/[0.12]">
              <div className="mb-3 flex items-start justify-between gap-3">
                <div className="min-w-0">
                  <div className="flex items-center gap-1.5 flex-wrap">
                    <span className="text-[13px] font-semibold text-white">{template.title}</span>
                    {template.required && <span className="text-[9px] text-[#e6f578]/80 uppercase tracking-widest">必备</span>}
                  </div>
                  <p className="mt-1 line-clamp-2 text-[11px] leading-relaxed text-white/45">{template.description}</p>
                </div>
                <div className="flex shrink-0 flex-col items-end gap-1 text-right">
                  <span className={`chip text-[10px] py-0 ${template.kind === 'patent' ? 'bg-[#e6f578]/15 text-[#e6f578] border-[#e6f578]/30' : template.kind === 'production' ? 'bg-[#d6b36a]/15 text-[#f2d38c] border-[#d6b36a]/30' : template.kind === 'accessories' ? 'bg-[#8cb478]/15 text-[#cfe7a7] border-[#8cb478]/30' : template.kind === 'marketing' ? 'bg-[#b6df72]/15 text-[#dff5a8] border-[#b6df72]/30' : 'chip-neutral'}`}>
                    {template.kind}
                  </span>
                  <span className="font-mono text-[9px] uppercase tracking-wider text-white/28">{template.outputFormat}</span>
                </div>
              </div>
              <div className="min-h-0 flex-1">
                {asset ? (
                  <pre className="h-full max-h-52 overflow-y-auto rounded-lg bg-black/32 p-3 text-[11px] leading-relaxed text-white/72 ring-1 ring-white/[0.06] whitespace-pre-wrap">
                    {asset.content}
                  </pre>
                ) : (
                  <div className="grid h-full min-h-28 place-items-center rounded-lg border border-dashed border-white/10 bg-black/16 text-[11px] text-white/28">
                    待生成文字
                  </div>
                )}
              </div>
              <div className="mt-3 flex items-center justify-between gap-3">
                <span className={`text-[10px] ${asset ? 'text-[#dff5a8]' : 'text-white/25'}`}>
                  {asset ? '完成' : '待生成'}
                </span>
                <button
                  onClick={() => setShowPromptId(isOpen ? null : template.id)}
                  className="text-[10px] text-white/30 hover:text-[#cfe7a7] transition-colors flex items-center gap-1"
                >
                  <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
                    <path d={isOpen ? 'M6 9l6 6 6-6' : 'M9 6l6 6-6 6'} strokeLinecap="round" />
                  </svg>
                  Prompt
                </button>
              </div>
              {isOpen && (
                <pre className="mt-3 p-2 text-[10px] text-white/60 bg-black/40 rounded-lg ring-1 ring-white/[0.07] font-mono whitespace-pre-wrap break-all max-h-28 overflow-y-auto">
                  {template.promptTemplate}
                </pre>
              )}
            </div>
          );
        })}
      </div>
    </section>
  );
}

/* ── Video Section ────────────────────────────── */
function VideoSection({ videoLoading, primaryImage, locked, session, onGenerateVideo, onRefreshVideo }: {
  videoLoading: string | null;
  primaryImage: GenImage;
  locked: boolean;
  session: GenSession;
  onGenerateVideo: (image: GenImage, template: typeof VIDEO_TEMPLATES[number]) => void;
  onRefreshVideo: (taskId: string) => void;
}) {
  const [showPromptId, setShowPromptId] = useState<string | null>(null);
  const videoTasks = session.videoTasks ?? [];
  const byTemplate = new Map(videoTasks.map(task => [task.templateId, task]));
  const builtInIds = new Set<string>(VIDEO_TEMPLATES.map(template => template.id));
  const extraTasks = videoTasks.filter(task => !builtInIds.has(task.templateId) && !/_part[12]$/.test(task.templateId));
  const videoItems = [
    ...VIDEO_TEMPLATES.map(template => ({
      id: template.id,
      title: template.title,
      description: template.description,
      duration: template.duration,
      ratio: template.ratio,
      promptTemplate: template.promptTemplate,
      template,
    })),
    ...extraTasks.map(task => ({
      id: task.templateId,
      title: task.title,
      description: task.description || '已回填的合成视频成片',
      duration: task.duration,
      ratio: task.ratio,
      promptTemplate: task.prompt,
      template: null,
    })),
  ];
  const submittedCount = videoItems.filter(item => byTemplate.has(item.id)).length;
  const totalCount = Math.max(videoItems.length, 1);

  return (
    <section className={`card overflow-hidden ${locked ? 'opacity-60' : ''}`} id="pack-video" aria-disabled={locked}>
      <div className="p-4 flex items-center gap-3">
        <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-[#e6f578] to-[#8cb478] flex items-center justify-center text-white text-[11px] font-bold shrink-0">V</div>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <span className="text-sm font-semibold text-white">Seedance 视频</span>
            <span className="text-[10px] text-white/35">异步任务 · 宣发 / 展示短片</span>
          </div>
          <div className="mt-2 flex items-center gap-2">
            <div className="flex-1 h-1 rounded-full bg-white/[0.06] overflow-hidden">
              <div className="h-full bg-gradient-to-r from-[#e6f578] to-[#8cb478]" style={{ width: `${Math.round((submittedCount / totalCount) * 100)}%` }} />
            </div>
            <span className="text-[10px] font-mono text-white/35 shrink-0">{submittedCount}/{totalCount}</span>
          </div>
        </div>
        <div className="flex items-center gap-2 shrink-0">
          <span className="chip chip-violet text-[10px]">Seedance</span>
        </div>
      </div>

      <div className="grid grid-cols-1 gap-3 border-t border-white/[0.05] p-4 xl:grid-cols-2">
        {videoItems.map(item => {
          const isOpen = showPromptId === item.id;
          const task = byTemplate.get(item.id);
          const loadingThis = videoLoading === item.id;
          return (
            <div key={item.id} className="min-w-0 overflow-hidden rounded-[8px] bg-white/[0.025] ring-1 ring-white/[0.05] transition-all hover:ring-white/[0.12]">
              <div className="relative bg-black/70" style={{ aspectRatio: item.ratio.replace(':', ' / ') }}>
                {task?.videoUrl ? (
                  <HoverVideoPreview
                    src={task.videoUrl}
                    aspectRatio={item.ratio}
                    className="h-full w-full object-contain"
                  />
                ) : (
                  <div className="flex h-full w-full flex-col items-center justify-center gap-1 bg-gradient-to-br from-[#e6f578]/12 to-[#8cb478]/12 text-[#e6f578]">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
                      <path d="M8 5.2v13.6L18.5 12 8 5.2z" />
                    </svg>
                    <span className="text-[10px] font-mono">{item.duration}s</span>
                  </div>
                )}
                <div className="pointer-events-none absolute inset-x-0 bottom-0 flex items-center justify-between bg-gradient-to-t from-black/82 to-transparent p-2">
                  <span className="rounded-[6px] bg-black/58 px-2 py-0.5 text-[9px] font-semibold text-white/72">{item.ratio}</span>
                  <span className="rounded-[6px] bg-[#e6f578]/90 px-2 py-0.5 text-[9px] font-bold text-[#081006]">{item.duration}s</span>
                </div>
              </div>
              <div className="space-y-2 p-3">
                <div className="flex items-start justify-between gap-3">
                  <div className="min-w-0">
                    <div className="flex items-center gap-1.5 flex-wrap">
                      <span className="text-[13px] font-semibold text-white">{item.title}</span>
                      {!item.template && <span className="chip chip-live text-[10px] py-0">回填</span>}
                    </div>
                    <p className="mt-1 line-clamp-2 text-[11px] leading-relaxed text-white/45">{item.description}</p>
                  </div>
                  <span className={`shrink-0 text-[10px] ${task ? 'text-[#dff5a8]' : 'text-white/25'}`}>
                    {task?.status ?? '待提交'}
                  </span>
                </div>
                {task && (
                  <div className="rounded-lg bg-black/28 p-2 text-[10px] leading-relaxed text-white/48 ring-1 ring-white/[0.06]">
                    <div className="flex flex-wrap items-center gap-2">
                      <span className="text-[#dff5a8]">{task.status}</span>
                      {task.taskId && <span className="font-mono text-white/34">{task.taskId}</span>}
                    </div>
                  </div>
                )}
                <div className="flex flex-wrap items-center justify-between gap-2">
                  <button
                    onClick={() => setShowPromptId(isOpen ? null : item.id)}
                    className="text-[10px] text-white/30 hover:text-[#e6f578] transition-colors flex items-center gap-1"
                  >
                    <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
                      <path d={isOpen ? 'M6 9l6 6 6-6' : 'M9 6l6 6-6 6'} strokeLinecap="round" />
                    </svg>
                    Prompt
                  </button>
                  <div className="flex items-center gap-2">
                    {task?.videoUrl && (
                      <>
                        <a href={task.videoUrl} target="_blank" rel="noreferrer" className="btn btn-outline px-3 py-1.5 text-[11px]">
                          打开
                        </a>
                        <a href={task.videoUrl} download={`${session.id}_${item.id}.mp4`} className="btn btn-outline px-3 py-1.5 text-[11px]">
                          下载
                        </a>
                      </>
                    )}
                    <button
                      onClick={() => task?.taskId ? onRefreshVideo(task.taskId) : item.template ? onGenerateVideo(primaryImage, item.template) : undefined}
                      disabled={Boolean(videoLoading) || locked || task?.status === 'succeeded' || (!item.template && !task?.taskId)}
                      className="btn btn-primary text-[11px] px-3 py-1.5 disabled:opacity-40"
                      title={locked ? '四个图片包完成后解锁视频任务' : undefined}
                    >
                      {locked ? '锁定' : loadingThis ? '...' : task ? task.status === 'succeeded' ? '完成' : '刷新' : '提交'}
                    </button>
                  </div>
                </div>
                {isOpen && (
                  <pre className="p-2 text-[10px] text-white/60 bg-black/40 rounded-lg ring-1 ring-white/[0.07] font-mono whitespace-pre-wrap break-all max-h-28 overflow-y-auto">
                    {item.promptTemplate}
                  </pre>
                )}
              </div>
            </div>
          );
        })}
      </div>
    </section>
  );
}

/* ── Section Nav ──────────────────────────────── */
const NAV_ITEMS = [
  { id: 'pack-patent', label: '专利', accent: 'from-[#e6f578] to-[#d6b36a]' },
  { id: 'pack-accessories', label: '配件', accent: 'from-[#8cb478] to-[#547a43]' },
  { id: 'pack-production', label: '生产', accent: 'from-[#d6b36a] to-[#b6813c]' },
  { id: 'pack-marketing', label: '宣发', accent: 'from-[#b6df72] to-[#4f9a56]' },
  { id: 'pack-text', label: '文字', accent: 'from-[#8cb478] to-[#d6b36a]' },
  { id: 'pack-video', label: '视频', accent: 'from-[#e6f578] to-[#8cb478]' },
];

function SectionNav({ active, onChange }: { active: string; onChange: (id: string) => void }) {
  return (
    <div className="flex items-center gap-1 overflow-x-auto scrollbar-none">
      {NAV_ITEMS.map(item => (
        <button
          key={item.id}
          onClick={() => onChange(item.id)}
          className={`shrink-0 px-3 py-1.5 rounded-lg text-xs font-medium transition-all ${
            active === item.id
              ? `text-[#081006] bg-gradient-to-r ${item.accent} shadow-sm`
              : 'text-white/45 hover:text-white/70 hover:bg-[#e6f578]/[0.06]'
          }`}
        >
          {item.label}
        </button>
      ))}
    </div>
  );
}

/* ── Main Export ──────────────────────────────── */
const totalImageSlots = PACK_ORDER.reduce((sum, kind) => sum + PACK_TEMPLATES[kind].length, 0);

function packForKind(packs: AssetPack[], kind: PackKind, sourceImageId: string) {
  return packs.find(pack => pack.kind === kind && pack.sourceImageId === sourceImageId);
}

function isPackComplete(pack: AssetPack | undefined, kind: PackKind) {
  return Boolean(pack && pack.assets.length >= PACK_TEMPLATES[kind].length);
}

function previousPackLabel(kind: PackKind) {
  const index = PACK_ORDER.indexOf(kind);
  if (index <= 0) return null;
  return PACK_LABELS[PACK_ORDER[index - 1]];
}

function packPanelState(packs: AssetPack[], kind: PackKind, primaryImageId: string, characterReady: boolean) {
  const pack = packForKind(packs, kind, primaryImageId);
  const index = PACK_ORDER.indexOf(kind);
  const previousKind = index > 0 ? PACK_ORDER[index - 1] : null;
  const previousComplete = !previousKind || isPackComplete(packForKind(packs, previousKind, primaryImageId), previousKind);
  const locked = !characterReady || !previousComplete;
  const lockReason = !characterReady
    ? '先锁定角色设定，然后从专利包开始。'
    : previousComplete
      ? undefined
      : `请先完成${previousPackLabel(kind)}，再生成${PACK_LABELS[kind]}。`;
  return { pack, index, locked, lockReason };
}

export default function PackPanel({
  session,
  activeNav,
  onActiveNavChange,
  textLoading,
  videoLoading,
  onGenerateText,
  onGenerateVideo,
  onRefreshVideo,
}: {
  session: GenSession;
  activeNav: string;
  onActiveNavChange: (id: string) => void;
  textLoading: boolean;
  videoLoading: string | null;
  onGenerateText: () => void;
  onGenerateVideo: (image: GenImage, template: typeof VIDEO_TEMPLATES[number]) => void;
  onRefreshVideo: (taskId: string) => void;
}) {
  const selectedImages = session.images.filter(image => image.status === 'selected');
  const primaryImage = selectedImages[0] ?? null;
  const packs = session.packs ?? [];
  const characterReady = Boolean(session.characterSpec);

  if (!primaryImage) {
    return (
      <section className="card h-full p-6">
        <div className="flex items-start gap-4">
          <div className="w-8 h-8 rounded-[8px] bg-white/[0.05] border border-white/[0.08] flex items-center justify-center text-white/30 text-sm">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" aria-hidden="true">
              <path d="M4 7h16M7 4v16M17 4v16M4 17h16" strokeLinecap="round" />
            </svg>
          </div>
          <div>
            <span className="section-eyebrow">Step · 03 · Assets</span>
            <h2 className="mt-1.5 text-sm font-semibold text-white">选中主方案后展开资产清单</h2>
            <p className="mt-1 text-[11px] text-white/40">
              在上方九宫格选中一个方案，这里会展开 {totalImageSlots} 个图片位 + {TEXT_TEMPLATES.length} 个文案位 + {VIDEO_TEMPLATES.length} 个视频任务。
            </p>
          </div>
        </div>
      </section>
    );
  }

  const completedPackCount = PACK_ORDER.filter(kind => isPackComplete(packForKind(packs, kind, primaryImage.id), kind)).length;
  const imagePacksComplete = completedPackCount === PACK_ORDER.length;
  const activePackKind = PACK_ORDER.find(kind => activeNav === `pack-${kind}`);

  return (
    <div className="flex h-full min-h-0 flex-col gap-3">
      <section className="card shrink-0 p-3">
        <div className="mb-3 flex items-center justify-between gap-3">
          <div className="min-w-0">
            <span className="section-eyebrow">Asset Details</span>
            <h2 className="mt-1 text-sm font-semibold text-white">生成明细</h2>
          </div>
          <span className="shrink-0 text-[10px] text-white/35">查看明细</span>
        </div>
        <SectionNav active={activeNav} onChange={onActiveNavChange} />
      </section>

      <div className="pack-scroll min-h-0 flex-1 overflow-y-auto pr-1" key={activeNav}>
        {activePackKind ? (() => {
          const { pack, index, locked, lockReason } = packPanelState(packs, activePackKind, primaryImage.id, characterReady);
          return (
            <PackSection
              kind={activePackKind}
              pack={pack}
              locked={locked}
              lockReason={lockReason}
              stepIndex={index + 1}
            />
          );
        })() : (
          <div className={imagePacksComplete ? '' : 'opacity-55'}>
          {!imagePacksComplete && (
            <div className="mb-3 rounded-[8px] border border-white/[0.06] bg-black/20 px-3 py-2 text-[11px] text-white/38">
              文案和视频在四个图片包完成后解锁。
            </div>
          )}
            {activeNav === 'pack-text' ? (
              <TextTemplateSection
                locked={!imagePacksComplete}
                session={session}
                loading={textLoading}
                onGenerateText={onGenerateText}
              />
            ) : (
              <VideoSection
                videoLoading={videoLoading}
                primaryImage={primaryImage}
                locked={!imagePacksComplete}
                session={session}
                onGenerateVideo={onGenerateVideo}
                onRefreshVideo={onRefreshVideo}
              />
            )}
          </div>
        )}
      </div>
    </div>
  );
}
