'use client';

import { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { PACK_LABELS, PACK_ORDER, PACK_TEMPLATES } from '@/lib/templates';
import type { GenSession, PackKind } from '@/lib/types';
import ResultGrid from './ResultGrid';

export type ProjectGalleryDrawerProps = {
  session: GenSession;
  activeNav: string;
  onAction: (imageId: string, action: 'select' | 'reject' | 'reset') => void;
};

type GalleryItem = {
  id: string;
  url: string;
  title: string;
  description?: string;
  status?: string;
  aspectRatio?: string;
  mediaType?: 'image' | 'video';
  downloadName?: string;
};

type GalleryPanel = {
  mode: 'pack' | 'empty' | 'project' | 'video';
  kind?: PackKind;
  label: string;
  description: string;
  total: number;
  images: GalleryItem[];
};

function statusClass(status?: string) {
  if (status === 'selected') return 'ring-[#e6f578]/80 shadow-[0_0_24px_-12px_rgba(230,245,120,0.9)]';
  if (status === 'rejected') return 'opacity-45 grayscale ring-white/10';
  return 'ring-white/12 hover:ring-white/28';
}

function aspectCss(aspectRatio?: string) {
  if (!aspectRatio) return '1 / 1';
  if (aspectRatio === 'long') return '1 / 3';
  return aspectRatio.replace(':', ' / ');
}

function activeKindFromNav(activeNav: string): PackKind | null {
  const kind = PACK_ORDER.find(item => activeNav === `pack-${item}`);
  return kind ?? null;
}

function galleryForPanel(session: GenSession, activeNav: string): GalleryPanel {
  const kind = activeKindFromNav(activeNav);
  const selectedImages = session.images.filter(image => image.status === 'selected');
  const primaryImage = selectedImages[0] ?? session.images[0] ?? null;

  if (kind) {
    const pack = session.packs?.find(item => item.kind === kind && (!primaryImage || item.sourceImageId === primaryImage.id))
      ?? session.packs?.find(item => item.kind === kind);
    const images: GalleryItem[] = pack?.assets.map(asset => ({
      id: asset.id,
      url: asset.url,
      title: asset.title,
      description: asset.description,
      status: asset.status,
      aspectRatio: asset.aspectRatio,
    })) ?? [];
    return {
      mode: 'pack' as const,
      kind,
      label: PACK_LABELS[kind],
      description: `${PACK_LABELS[kind]}当前区块图片`,
      total: PACK_TEMPLATES[kind].length,
      images,
    };
  }

  if (activeNav === 'pack-text') {
    return { mode: 'empty' as const, label: '文字', description: '文字区块暂无图片素材', total: 0, images: [] as GalleryItem[] };
  }
  if (activeNav === 'pack-video') {
    const videos: GalleryItem[] = (session.videoTasks ?? [])
      .filter(task => !/_part[12]$/.test(task.templateId))
      .filter(task => task.videoUrl)
      .map(task => ({
        id: task.templateId,
        url: task.videoUrl!,
        title: task.title,
        description: `${task.ratio} · ${task.duration}s · ${task.status}`,
        status: task.status,
        aspectRatio: task.ratio,
        mediaType: 'video' as const,
        downloadName: `${session.id}_${task.templateId}.mp4`,
      }));
    return {
      mode: 'video' as const,
      label: '视频',
      description: '当前项目所有视频成片',
      total: videos.length,
      images: videos,
    };
  }

  return {
    mode: 'project',
    label: '项目',
    description: session.characterSpec?.name || session.prompt || '当前项目',
    total: session.images.length,
    images: session.images.map((image, index) => ({
      id: image.id,
      url: image.url,
      title: `主图库 ${index + 1}`,
      description: undefined,
      status: image.status,
      aspectRatio: '1:1',
    })),
  };
}

export default function ProjectGalleryDrawer({ session, activeNav, onAction }: ProjectGalleryDrawerProps) {
  const [open, setOpen] = useState(false);
  const [mounted, setMounted] = useState(false);
  const [preview, setPreview] = useState<GalleryItem | null>(null);
  const gallery = galleryForPanel(session, activeNav);
  const downloadHref = gallery.kind && gallery.images.length
    ? `/api/packs/download?sessionId=${encodeURIComponent(session.id)}&kind=${encodeURIComponent(gallery.kind)}`
    : null;

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

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

  const drawer = (
    <>
      <div className={`gallery-backdrop ${open ? 'pointer-events-auto opacity-100' : 'pointer-events-none opacity-0'}`} onClick={() => setOpen(false)} />
      <aside className={`gallery-drawer ${open ? 'is-open' : ''}`} aria-hidden={!open}>
        <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">Project Gallery</span>
            <h2 className="mt-2 text-lg font-semibold text-white">{gallery.label}图库</h2>
            <p className="mt-1 line-clamp-2 text-xs leading-relaxed text-white/42">
              {gallery.description}
            </p>
          </div>
          <button
            onClick={() => setOpen(false)}
            tabIndex={open ? 0 : -1}
            className="grid h-10 w-10 shrink-0 cursor-pointer 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">
          {open && gallery.mode === 'project' ? (
            <ResultGrid images={session.images} onAction={onAction} />
          ) : (
            <div className="gallery-drawer-grid">
              {gallery.images.map((image, index) => (
                <div key={image.id} className="gallery-drawer-card">
                  <div className="gallery-drawer-card__image" style={{ aspectRatio: aspectCss(image.aspectRatio) }}>
                    {image.mediaType === 'video' ? (
                      <video src={image.url} controls muted playsInline preload="metadata" />
                    ) : (
                      <img src={image.url} alt={image.title} />
                    )}
                  </div>
                  <div className="mt-3 min-w-0">
                    <div className="flex min-w-0 items-center gap-2">
                      <span className="truncate text-[12px] font-semibold text-white">{image.title}</span>
                      <span className="shrink-0 font-mono text-[10px] text-[#dff5a8]">{index + 1}</span>
                    </div>
                    {image.description && (
                      <p className="mt-1 line-clamp-2 text-[10px] leading-relaxed text-white/42">{image.description}</p>
                    )}
                    {image.mediaType === 'video' && (
                      <a href={image.url} download={image.downloadName} className="mt-2 inline-flex text-[10px] font-semibold text-[#e6f578] hover:text-white">
                        下载视频
                      </a>
                    )}
                  </div>
                </div>
              ))}
              {!gallery.images.length && (
                <div className="gallery-empty-state">当前区块还没有可显示的图片。</div>
              )}
            </div>
          )}
        </div>
      </aside>
    </>
  );

  const centerPreview = preview ? (
    <div className="gallery-center-preview" aria-hidden="true">
      {preview.mediaType === 'video' ? (
        <video src={preview.url} muted autoPlay loop playsInline />
      ) : (
        <img src={preview.url} alt="" />
      )}
    </div>
  ) : null;

  return (
    <>
      <aside className="gallery-rail flex h-full min-h-0 flex-col items-center gap-3 overflow-hidden rounded-[8px] border border-white/10 bg-white/[0.045] p-2 backdrop-blur-xl">
        <button
          onClick={() => setOpen(true)}
          className="flex h-12 w-full cursor-pointer flex-col items-center justify-center rounded-[8px] bg-[#e6f578] text-[#081006] transition-colors hover:bg-[#f0fb82]"
          title={`打开${gallery.label}图库`}
          aria-label={`打开${gallery.label}图库`}
        >
          <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" aria-hidden="true">
            <rect x="3" y="5" width="18" height="14" rx="2" />
            <path d="m7 14 3-3 3 3 2-2 2 2" strokeLinecap="round" strokeLinejoin="round" />
            <circle cx="8" cy="9" r="1.2" fill="currentColor" stroke="none" />
          </svg>
          <span className="mt-0.5 text-[9px] font-semibold">图库</span>
        </button>

        {downloadHref && (
          <a
            href={downloadHref}
            className="gallery-download-button"
            title={`打包下载${gallery.label}图片`}
            aria-label={`打包下载${gallery.label}图片`}
          >
            <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" aria-hidden="true">
              <path d="M12 4v10" strokeLinecap="round" />
              <path d="m8 10 4 4 4-4" strokeLinecap="round" strokeLinejoin="round" />
              <path d="M5 19h14" strokeLinecap="round" />
            </svg>
            <span>下载</span>
          </a>
        )}

        <div className="w-full rounded-[8px] bg-black/22 px-1.5 py-2 text-center text-[10px] text-white/42">
          <b className="block text-[13px] text-[#e6f578]">{gallery.images.length}</b>
          <span>/ {gallery.total}</span>
        </div>

        <div className="gallery-thumb-list flex min-h-0 w-full flex-1 flex-col gap-2 overflow-y-auto pr-0.5">
          {gallery.images.map((image, index) => (
            <button
              key={image.id}
              onClick={() => setOpen(true)}
              onMouseEnter={() => setPreview(image)}
              onMouseLeave={() => setPreview(null)}
              onFocus={() => setPreview(image)}
              onBlur={() => setPreview(null)}
              className={`gallery-rail-thumb relative w-full cursor-pointer overflow-hidden rounded-[8px] bg-white ring-1 transition-all ${statusClass(image.status)}`}
              style={{ aspectRatio: aspectCss(image.aspectRatio) }}
              title={`查看${image.title}`}
              aria-label={`查看${image.title}`}
            >
              {image.mediaType === 'video' ? (
                <video src={image.url} muted playsInline preload="metadata" className="h-full w-full object-contain" />
              ) : (
                <img src={image.url} alt="" className="h-full w-full object-contain" />
              )}
              <span className="absolute left-1 top-1 rounded-[6px] bg-black/60 px-1.5 py-0.5 text-[9px] font-semibold text-white">
                {index + 1}
              </span>
              {image.mediaType === 'video' && (
                <span className="absolute right-1 top-1 rounded-[6px] bg-black/70 px-1.5 py-0.5 text-[8px] font-semibold text-[#e6f578]">▶</span>
              )}
              {image.status === 'selected' && (
                <span className="absolute right-1 top-1 grid h-5 w-5 place-items-center rounded-full bg-[#e6f578] text-[10px] font-bold text-[#081006]">✓</span>
              )}
              {image.status === 'rejected' && (
                <span className="absolute right-1 top-1 grid h-5 w-5 place-items-center rounded-full bg-black/65 text-[10px] font-bold text-white">×</span>
              )}
            </button>
          ))}
          {!gallery.images.length && (
            <div className="gallery-rail-empty">暂无图片</div>
          )}
        </div>
      </aside>

      {mounted ? createPortal(drawer, document.body) : null}
      {mounted && centerPreview ? createPortal(centerPreview, document.body) : null}
    </>
  );
}
