'use client';

import { useCallback, useEffect, useState } from 'react';
import PromptPanel from '@/components/PromptPanel';
import ResultGrid from '@/components/ResultGrid';
import Sidebar from '@/components/Sidebar';
import PackPanel from '@/components/PackPanel';
import { OasisCanvas } from '@/components/login/OasisCanvas';
import type {
  GenImage,
  GenSession,
  GenerateAllPacksResponse,
  GeneratePackResponse,
  GenerateResponse,
  LockCharacterResponse,
  PackKind,
  ProjectFromUploadResponse,
  RegenerateAssetResponse,
  UploadImageResponse,
  UploadedImageRole,
  VideoGenerationResponse,
} from '@/lib/types';
import type { VIDEO_TEMPLATES } from '@/lib/templates';

export default function Home() {
  const [sessions, setSessions] = useState<GenSession[]>([]);
  const [current, setCurrent] = useState<GenSession | null>(null);
  const [loading, setLoading] = useState(false);
  const [loadingKind, setLoadingKind] = useState<PackKind | null>(null);
  const [allLoading, setAllLoading] = useState(false);
  const [characterLoading, setCharacterLoading] = useState(false);
  const [videoLoading, setVideoLoading] = useState(false);
  const [uploadLoading, setUploadLoading] = useState(false);
  const [provider, setProvider] = useState<string>('?');
  const [sidebarOpen, setSidebarOpen] = useState(true);

  const refreshSessions = useCallback(async () => {
    const r = await fetch('/api/sessions');
    const d = await r.json();
    setSessions(d.sessions);
    return d.sessions as GenSession[];
  }, []);

  useEffect(() => { refreshSessions(); }, [refreshSessions]);

  async function handleGenerate(opts: { prompt: string; refImages: string[]; count: number; style?: string }) {
    setLoading(true);
    try {
      const r = await fetch('/api/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(opts),
      });
      if (!r.ok) {
        alert('生成失败：' + (await r.text()));
        return;
      }
      const d: GenerateResponse = await r.json();
      setProvider(d.provider);
      const all = await refreshSessions();
      const s = all.find(x => x.id === d.sessionId) ?? null;
      setCurrent(s);
    } finally {
      setLoading(false);
    }
  }

  async function uploadImage(file: File, role: UploadedImageRole) {
    const form = new FormData();
    form.set('image', file);
    form.set('role', role);
    const r = await fetch('/api/uploads', { method: 'POST', body: form });
    if (!r.ok) throw new Error(await r.text());
    const d: UploadImageResponse = await r.json();
    return d.uploadedImage;
  }

  async function handleUploadProject(opts: {
    mode: 'remix' | 'replicate';
    files: Array<{ file: File; role: 'reference' | 'subject' }>;
    prompt?: string;
    styleId?: string;
    count?: number;
  }) {
    if (uploadLoading) return;
    setUploadLoading(true);
    try {
      const uploadedImages = await Promise.all(opts.files.map(item => uploadImage(item.file, item.role)));
      const r = await fetch('/api/projects/from-upload', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          uploadedImages,
          mode: opts.mode,
          remixPrompt: opts.mode === 'remix' ? opts.prompt : undefined,
          userHint: opts.mode === 'replicate' ? opts.prompt : undefined,
          styleId: opts.styleId,
          count: opts.count,
        }),
      });
      if (!r.ok) {
        alert('上传项目创建失败：' + (await r.text()));
        return;
      }
      const d: ProjectFromUploadResponse = await r.json();
      setProvider(d.provider);
      const all = await refreshSessions();
      const s = all.find(x => x.id === d.sessionId) ?? null;
      setCurrent(s);
    } catch (error) {
      alert('上传失败：' + String(error));
    } finally {
      setUploadLoading(false);
    }
  }

  async function handleAction(imageId: string, action: 'select' | 'reject' | 'reset') {
    if (!current) return;
    const r = await fetch('/api/select', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ sessionId: current.id, imageId, action }),
    });
    if (!r.ok) return;
    const d: { image: GenImage } = await r.json();
    setCurrent(prev => prev ? {
      ...prev,
      images: prev.images.map(i => i.id === imageId ? d.image : i),
    } : prev);
    refreshSessions();
  }

  async function handleGeneratePack(image: GenImage, kind: PackKind) {
    if (!current || loadingKind) return;
    setLoadingKind(kind);
    try {
      const r = await fetch('/api/packs/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ sessionId: current.id, imageId: image.id, kind, background: true }),
      });
      if (!r.ok) {
        alert('素材包生成失败：' + (await r.text()));
        return;
      }
      const d: GeneratePackResponse = await r.json();
      setProvider(d.provider);
      const all = await refreshSessions();
      const updated = all.find(x => x.id === current.id) ?? null;
      setCurrent(updated);
      scheduleSessionRefresh(current.id);
    } finally {
      setLoadingKind(null);
    }
  }

  async function reloadCurrent(sessionId: string) {
    const all = await refreshSessions();
    const updated = all.find(x => x.id === sessionId) ?? null;
    setCurrent(updated);
    return updated;
  }

  function scheduleSessionRefresh(sessionId: string, remaining = 90) {
    if (remaining <= 0) return;
    window.setTimeout(async () => {
      const updated = await reloadCurrent(sessionId);
      const hasDraftPack = updated?.packs?.some(pack => pack.status === 'draft') ?? false;
      if (hasDraftPack || remaining > 84) scheduleSessionRefresh(sessionId, remaining - 1);
    }, 5000);
  }

  async function handleLockCharacter(image: GenImage) {
    if (!current || characterLoading) return;
    setCharacterLoading(true);
    try {
      const r = await fetch('/api/character/lock', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ sessionId: current.id, imageId: image.id, force: true }),
      });
      if (!r.ok) {
        alert('角色锁定失败：' + (await r.text()));
        return;
      }
      const d: LockCharacterResponse = await r.json();
      setProvider(d.provider);
      await reloadCurrent(current.id);
    } finally {
      setCharacterLoading(false);
    }
  }

  async function handleGenerateAll(image: GenImage) {
    if (!current || allLoading) return;
    setAllLoading(true);
    try {
      const r = await fetch('/api/packs/generate-all', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ sessionId: current.id, imageId: image.id, background: true }),
      });
      if (!r.ok) {
        alert('完整三包生成失败：' + (await r.text()));
        return;
      }
      const d: GenerateAllPacksResponse = await r.json();
      setProvider(d.provider);
      await reloadCurrent(current.id);
      scheduleSessionRefresh(current.id);
    } finally {
      setAllLoading(false);
    }
  }

  async function handleRegenerateAsset(assetId: string, userRefinement?: string) {
    if (!current) return;
    const r = await fetch(`/api/assets/${encodeURIComponent(assetId)}/regenerate`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ sessionId: current.id, userRefinement, confirmCost: true }),
    });
    if (!r.ok) {
      alert('单张重做失败：' + (await r.text()));
      return;
    }
    const d: RegenerateAssetResponse = await r.json();
    setProvider(d.provider);
    await reloadCurrent(current.id);
  }

  function resolveVideoAnchor(image: GenImage) {
    const packs = current?.packs ?? [];
    const mktFront = packs.find(pack => pack.kind === 'marketing')?.assets.find(asset => asset.templateId === 'mkt_white_front');
    const patentFront = packs.find(pack => pack.kind === 'patent')?.assets.find(asset => asset.templateId === 'patent_front');
    const cleanReference = current?.characterSpec?.cleanReferenceImageUrl;
    if (mktFront) return { url: mktFront.url, label: '宣发白底图' };
    if (patentFront) return { url: patentFront.url, label: '专利主图' };
    if (cleanReference) return { url: cleanReference, label: 'L1 白底锚图' };
    return { url: image.url, label: '意向图' };
  }

  async function handleGenerateVideo(image: GenImage, template: typeof VIDEO_TEMPLATES[number]) {
    if (!current || videoLoading) return;
    setVideoLoading(true);
    try {
      const character = current.characterSpec
        ? `${current.characterSpec.name}，${current.characterSpec.oneLiner}`
        : current.prompt;
      const prompt = template.promptTemplate.replace('{character}', character);
      const anchor = resolveVideoAnchor(image);
      const r = await fetch('/api/video/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          prompt,
          imageUrl: anchor.url,
          duration: template.duration,
          ratio: template.ratio,
          generateAudio: true,
          watermark: false,
        }),
      });
      if (!r.ok) {
        alert('Seedance 视频提交失败：' + (await r.text()));
        return;
      }
      const d: VideoGenerationResponse = await r.json();
      alert(`Seedance 任务已提交：${d.taskId ?? d.status}；参考：${anchor.label}`);
    } finally {
      setVideoLoading(false);
    }
  }

  async function handleLogout() {
    await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' });
    window.location.href = '/login';
  }

  return (
    <div className="app-oasis relative h-screen overflow-hidden text-white">
      <OasisCanvas />
      <div className="app-oasis-shade" />
      <div className="app-grass-floor" />
      <div className="relative z-10 flex h-screen text-white">
      <Sidebar
        open={sidebarOpen}
        onToggle={() => setSidebarOpen(v => !v)}
        sessions={sessions}
        currentId={current?.id ?? null}
        onPick={id => setCurrent(sessions.find(s => s.id === id) ?? null)}
        onNew={() => setCurrent(null)}
      />
      <main className="flex-1 overflow-y-auto">
        <div className="mx-auto max-w-[1240px] px-10 py-8">
          <header className="flex items-center justify-between mb-8 gap-4">
            <div className="flex items-center gap-3 min-w-0">
              <div className="w-9 h-9 rounded-[8px] bg-gradient-to-br from-[#e6f578] to-[#d6b36a] flex items-center justify-center shrink-0 shadow-glow-violet">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#081006" strokeWidth="2.5">
                  <path d="M12 2l2.5 6.5L21 11l-6.5 2.5L12 20l-2.5-6.5L3 11l6.5-2.5z" strokeLinejoin="round" />
                </svg>
              </div>
              <div className="min-w-0">
                <h1 className="text-base font-semibold tracking-tight leading-tight text-[#f8f7ef]">
                  AI Toy Patent
                  <span className="ml-2 text-white/48 font-normal text-sm">把一句想法变成专利 / 生产 / 宣发素材包</span>
                </h1>
                <p className="text-[11px] text-[#e6f578]/55 mt-0.5">批量出意向 · 快筛 · 锁定角色 · 一键四包 · Seedance 视频</p>
              </div>
            </div>
            <div className="flex items-center gap-2 shrink-0">
              {current && (
                <>
                  <a
                    href={`/api/gallery/${encodeURIComponent(current.id)}`}
                    target="_blank"
                    rel="noreferrer"
                    className="chip chip-neutral hover:border-[#e6f578]/40 hover:text-white transition-colors"
                  >
                    图库
                  </a>
                  <a
                    href={`/api/audit/${encodeURIComponent(current.id)}`}
                    target="_blank"
                    rel="noreferrer"
                    className="chip chip-neutral hover:border-[#e6f578]/40 hover:text-white transition-colors"
                  >
                    记录
                  </a>
                </>
              )}
              <button
                onClick={handleLogout}
                className="chip chip-neutral hover:border-[#e6f578]/40 hover:text-white transition-colors"
              >
                退出
              </button>
              <span className={provider === 'gpt' ? 'chip chip-live' : provider === '?' ? 'chip chip-neutral' : 'chip chip-mock'}>
                <span className={`w-1.5 h-1.5 rounded-full ${provider === 'gpt' ? 'bg-emerald-400' : provider === '?' ? 'bg-white/40' : 'bg-amber-400'}`} />
                {provider === 'gpt' ? 'GPT · gpt-image-2' : provider === 'mock' ? 'Mock · 占位图' : provider === '?' ? '待连接' : provider}
              </span>
            </div>
          </header>

          <div className="space-y-8">
            {!current && (
              <PromptPanel
                session={null}
                onGenerate={handleGenerate}
                onUploadProject={handleUploadProject}
                loading={loading}
                uploadLoading={uploadLoading}
              />
            )}
            {current && (
              <section className="space-y-5">
                <div className="flex items-end justify-between">
                  <div>
                    <span className="section-eyebrow">Step · 02 · Quick Screen</span>
                    <h2 className="mt-2 text-lg font-semibold text-white">本次生成</h2>
                    <p className="text-xs text-white/40 mt-1">
                      {new Date(current.createdAt).toLocaleString('zh-CN')}
                    </p>
                  </div>
                  <code className="text-[11px] text-white/30 font-mono">{current.id}</code>
                </div>
                <ResultGrid images={current.images} onAction={handleAction} />
                <PackPanel
                  session={current}
                  loadingKind={loadingKind}
                  allLoading={allLoading}
                  characterLoading={characterLoading}
                  videoLoading={videoLoading}
                  onGenerate={handleGeneratePack}
                  onGenerateAll={handleGenerateAll}
                  onLockCharacter={handleLockCharacter}
                  onRegenerateAsset={handleRegenerateAsset}
                  onGenerateVideo={handleGenerateVideo}
                />
              </section>
            )}
          </div>
        </div>
      </main>
      </div>
    </div>
  );
}
