'use client';

import { useState, useCallback, useMemo, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { useAuth } from '@/lib/auth-store';
import { useCustomApiKeys } from '@/lib/custom-api-store';
import { useManagedSystemApis } from '@/lib/managed-model-store';
import {
  VIDEO_ASPECT_RATIOS,
  VIDEO_DURATIONS,
  VIDEO_STYLES,
  CAMERA_MOVEMENTS,
  isCustomModel,
  isSystemModel,
  getCustomKeyId,
  getSystemApiId,
  buildCustomModelId,
  buildSystemModelId,
  calcVideoCredits,
} from '@/lib/model-config';
import { Sparkles, Loader2, Download, Wand2, Video, Film, History, ChevronDown, ChevronUp, KeyRound, Share2, Plus } from 'lucide-react';
import { useCreationHistory, getCreationMode, isPlaceholder, shareToGallery, isUrlPublished, type CreationRecord } from '@/lib/creation-history-store';
import { addCreditRecord } from '@/lib/credit-records-store';
import { downloadFile } from '@/lib/utils';
import { runGenerationFinalCountdown, runGenerationJob, type GenerationJobStatus } from '@/lib/generation-job-client';
import { useSiteConfig } from '@/lib/site-config';
import { toast } from 'sonner';
import Link from 'next/link';
import { CreationDetailDialog } from '@/components/creation-detail-dialog';
import { GenerationErrorPanel, createGenerationError, type GenerationErrorState } from '@/components/create/generation-error-panel';
import { ExpandablePromptTextarea } from '@/components/create/expandable-prompt-textarea';
import { GenerationTaskList, type ActiveGenerationTask } from '@/components/create/generation-task-list';
import { InspirationGalleryDialog } from '@/components/create/inspiration-gallery-dialog';
import { TEXT_TO_VIDEO_DRAFT_EVENT, TEXT_TO_VIDEO_DRAFT_KEY, type CreationReuseDraft } from '@/lib/creation-reuse';

export function TextToVideoPanel() {
  const { user, accessToken } = useAuth();
  const { config: siteConfig } = useSiteConfig();
  const membershipEnabled = siteConfig.membershipEnabled !== false;
  const { videoKeys, textKeys } = useCustomApiKeys();
  const managedSystemApis = useManagedSystemApis();

  const [prompt, setPrompt] = useState('');
  const [negativePrompt, setNegativePrompt] = useState('');
  const [aspectRatio, setAspectRatio] = useState('16:9');
  const [duration, setDuration] = useState('6');
  const [cameraMovement, setCameraMovement] = useState(CAMERA_MOVEMENTS[0]);
  const [style, setStyle] = useState(VIDEO_STYLES[0]);

  const [activeTasks, setActiveTasks] = useState<ActiveGenerationTask[]>([]);
  const [results, setResults] = useState<string[]>([]);
  const [generationError, setGenerationError] = useState<GenerationErrorState | null>(null);
  const [optimizing, setOptimizing] = useState(false);
  const [inspirationOpen, setInspirationOpen] = useState(false);
  const generating = activeTasks.length > 0;

  const { records, add: addRecord } = useCreationHistory();
  const [showHistory, setShowHistory] = useState(false);

  // History detail dialog
  const [selectedHistoryRecord, setSelectedHistoryRecord] = useState<CreationRecord | null>(null);
  const videoHistory = records.filter(r => getCreationMode(r) === 'text2video');

  const systemVideoApis = managedSystemApis.filter(api => api.type === 'video' && api.isActive);
  const systemTextApis = managedSystemApis.filter(api => api.type === 'text' && api.isActive);

  // Model options — only system + custom (no builtin)
  const modelOptions = useMemo(() => [
    ...systemVideoApis.map(api => ({ id: buildSystemModelId(api.id), label: `${api.name} (系统)`, group: '系统模型' })),
    ...videoKeys.map(k => ({ id: buildCustomModelId(k.id), label: `${k.modelName || k.provider} (自定义)`, group: '自定义模型' })),
  ], [systemVideoApis, videoKeys]);

  const hasModels = modelOptions.length > 0;

  const [selectedModel, setSelectedModel] = useState('');
  useEffect(() => {
    if (modelOptions.length > 0 && !modelOptions.find(o => o.id === selectedModel)) {
      const customOpt = modelOptions.find(o => o.group === '自定义模型');
      setSelectedModel(customOpt ? customOpt.id : modelOptions[0].id);
    }
  }, [modelOptions, selectedModel]);

  const applyVideoDraft = useCallback((draft: unknown) => {
    if (!draft || typeof draft !== 'object') return;
    const data = draft as CreationReuseDraft;
    if (typeof data.prompt === 'string') setPrompt(data.prompt);
    if (typeof data.negativePrompt === 'string') setNegativePrompt(data.negativePrompt);
    if (typeof data.model === 'string' && data.model.trim()) setSelectedModel(data.model.trim());
    if (typeof data.aspectRatio === 'string' && data.aspectRatio.trim()) setAspectRatio(data.aspectRatio.trim());
    if (typeof data.duration === 'string' && data.duration.trim()) setDuration(data.duration.trim());
    if (typeof data.cameraMovement === 'string' && data.cameraMovement.trim()) setCameraMovement(data.cameraMovement.trim());
    if (typeof data.style === 'string' && data.style.trim()) setStyle(data.style.trim());
  }, []);

  useEffect(() => {
    try {
      const raw = window.localStorage.getItem(TEXT_TO_VIDEO_DRAFT_KEY);
      if (raw) applyVideoDraft(JSON.parse(raw));
    } catch {
      // Ignore malformed local draft data.
    }

    const handleDraft = (event: Event) => {
      applyVideoDraft((event as CustomEvent).detail);
    };
    window.addEventListener(TEXT_TO_VIDEO_DRAFT_EVENT, handleDraft);
    return () => window.removeEventListener(TEXT_TO_VIDEO_DRAFT_EVENT, handleDraft);
  }, [applyVideoDraft]);

  const textModelOptions = useMemo(() => [
    ...textKeys.map(k => ({ id: buildCustomModelId(k.id), label: `${k.modelName || k.provider} (自定义)`, config: { customApiKeyId: k.id, modelName: k.modelName } })),
    ...systemTextApis.map(api => ({ id: buildSystemModelId(api.id), label: `${api.name} (系统)`, config: { systemApiId: api.id, modelName: api.modelName } })),
  ], [textKeys, systemTextApis]);

  const getCurrentModelLabel = useCallback(() => {
    if (isCustomModel(selectedModel)) {
      const key = videoKeys.find(k => k.id === getCustomKeyId(selectedModel));
      return key?.modelName || key?.provider || '自定义模型';
    }
    if (isSystemModel(selectedModel)) {
      const api = systemVideoApis.find(a => a.id === getSystemApiId(selectedModel));
      return api?.name || '系统模型';
    }
    return 'AI模型';
  }, [selectedModel, videoKeys, systemVideoApis]);

  const handleOptimizePrompt = useCallback(async () => {
    if (!prompt.trim()) { toast.error('请先输入视频描述'); return; }
    if (!user || !accessToken) { toast.error('请先登录后再优化提示词'); return; }
    if (textModelOptions.length === 0) { toast.error('未配置文本模型'); return; }

    setOptimizing(true);
    try {
      const textModel = textModelOptions[0];
      const modelLabel = getCurrentModelLabel();
      const res = await fetch('/api/generate/suggest-prompt', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),
        },
        body: JSON.stringify({
          prompt: prompt.trim(),
          modelName: textModel.config.modelName,
          customApiConfig: textModel.config,
          systemPrefix: `针对${modelLabel}视频生成优化提示词`,
        }),
      });
      const data = await res.json().catch(() => ({}));
      if (res.ok) {
        if (data.prompt) {
          setPrompt(data.prompt);
          if (typeof data.negativePrompt === 'string' && data.negativePrompt.trim()) {
            setNegativePrompt(data.negativePrompt.trim());
          }
          toast.success('提示词已优化');
        }
        else toast.error(data.error || '优化失败');
      } else toast.error(data.error || '提示词优化请求失败');
    } catch (err: unknown) {
      if (err instanceof DOMException && err.name === 'AbortError') {
        toast.error('请求超时，视频生成可能需要更长时间');
      } else {
        toast.error(err instanceof Error ? err.message : '网络错误，请重试');
      }
    }
    finally { setOptimizing(false); }
  }, [prompt, user, accessToken, textModelOptions, getCurrentModelLabel]);

  const credits = calcVideoCredits(duration, selectedModel);

  const updateActiveTask = useCallback((taskId: string, update: Partial<ActiveGenerationTask>) => {
    setActiveTasks(prev => prev.map(task => task.id === taskId ? { ...task, ...update } : task));
  }, []);

  const removeActiveTask = useCallback((taskId: string) => {
    setActiveTasks(prev => prev.filter(task => task.id !== taskId));
  }, []);

  const handleGenerate = useCallback(async () => {
    if (!prompt.trim()) { toast.error('请输入视频描述'); return; }
    if (!user) { toast.error('请先登录'); return; }

    setGenerationError(null);
    const taskId = `text2video-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
    try {
      setActiveTasks(prev => [
        ...prev,
        {
          id: taskId,
          title: '正在生成视频',
          startedAt: Date.now(),
          estimateSeconds: 300,
          jobStatus: null,
          finalCountdownSeconds: null,
        },
      ]);
      let requestBody: Record<string, unknown> = {
        prompt: prompt.trim(),
        negativePrompt: negativePrompt.trim() || undefined,
        model: selectedModel,
        aspectRatio,
        duration: Number(duration),
        fps: 30,
      };

      if (isCustomModel(selectedModel)) {
        const key = videoKeys.find(k => k.id === getCustomKeyId(selectedModel));
        if (key) {
          requestBody = { ...requestBody, model: key.modelName, customApiConfig: { customApiKeyId: key.id, modelName: key.modelName } };
        }
      } else if (isSystemModel(selectedModel)) {
        const api = systemVideoApis.find(a => a.id === getSystemApiId(selectedModel));
        if (api) {
          requestBody = { ...requestBody, model: api.modelName, customApiConfig: { systemApiId: api.id, modelName: api.modelName } };
        }
      }
      const data = await runGenerationJob<{ videos?: string[]; error?: string }>(
        'video',
        requestBody,
        { timeoutMs: 600_000, onStatus: (status: GenerationJobStatus) => updateActiveTask(taskId, { jobStatus: status }) },
      );
      await runGenerationFinalCountdown((seconds) => updateActiveTask(taskId, { finalCountdownSeconds: seconds }), 3);
      if (data.videos && data.videos.length > 0) {
        setResults(prev => [...data.videos!, ...prev]);
        setGenerationError(null);
        for (const url of data.videos) {
          addRecord({
            type: 'video', url, prompt: prompt.trim(),
            negativePrompt: negativePrompt.trim() || undefined,
            model: selectedModel,
            modelLabel: getCurrentModelLabel(),
            isCustomModel: isCustomModel(selectedModel) || isSystemModel(selectedModel),
            params: { creationMode: 'text2video', aspectRatio, duration, cameraMovement, style },
          });
        }
        toast.success('视频生成成功');
        if (membershipEnabled && credits > 0 && user) {
          const currentCredits = typeof user.creditsBalance === 'number' ? user.creditsBalance : 0;
          addCreditRecord({
            type: 'consume',
            amount: -credits,
            balanceAfter: Math.max(0, currentCredits - credits),
            description: `文生视频 - ${getCurrentModelLabel()}`,
          });
        }
      } else {
        setGenerationError(createGenerationError(data.error || '视频生成失败'));
      }
    } catch (err: unknown) {
      if (err instanceof DOMException && err.name === 'AbortError') {
        setGenerationError(createGenerationError('请求超时，视频生成可能需要更长时间'));
      } else {
        setGenerationError(createGenerationError(err instanceof Error ? err.message : '网络错误，请重试'));
      }
    }
    finally { removeActiveTask(taskId); }
  }, [prompt, negativePrompt, selectedModel, aspectRatio, duration, cameraMovement, style, user, videoKeys, systemVideoApis, getCurrentModelLabel, addRecord, credits, membershipEnabled, removeActiveTask, updateActiveTask]);

  const handleDownload = useCallback(async (url: string, index: number) => {
    const result = await downloadFile(url, `miaojing-video-${Date.now()}-${index}.mp4`);
    if (!result.ok) toast.error(result.error || '下载失败');
  }, []);

  const handleShareToGallery = useCallback((url: string) => {
    if (isUrlPublished(url)) {
      toast.info('该作品已分享到画廊');
      return;
    }
    shareToGallery({
      type: 'video',
      url,
      prompt: prompt.trim(),
      model: selectedModel,
      modelLabel: getCurrentModelLabel(),
    });
    toast.success('已分享到画廊');
  }, [prompt, selectedModel, getCurrentModelLabel]);

  return (
    <>
    <InspirationGalleryDialog mode="text2video" open={inspirationOpen} onOpenChange={setInspirationOpen} />
    <div className="grid min-h-[600px] grid-cols-1 gap-6 xl:grid-cols-[minmax(0,4fr)_minmax(0,6fr)]">
      {/* Left: Settings */}
      <div className="min-w-0 space-y-5 pb-8 pr-2">
        <div className="space-y-2">
          <Label>视频模型</Label>
          {hasModels ? (
            <Select value={selectedModel} onValueChange={setSelectedModel}>
              <SelectTrigger><SelectValue placeholder="选择模型" /></SelectTrigger>
              <SelectContent>
                {modelOptions.map(opt => (
                  <SelectItem key={opt.id} value={opt.id}>{opt.label}</SelectItem>
                ))}
              </SelectContent>
            </Select>
          ) : (
            <div className="liquid-glass-soft rounded-2xl border-dashed p-4 text-center space-y-2">
              <KeyRound className="h-8 w-8 mx-auto text-muted-foreground/50" />
              <p className="text-sm text-muted-foreground">暂无可用模型</p>
              <Link href="/profile" className="text-sm text-primary hover:underline">
                前往 我的 → API 中添加API密钥
              </Link>
            </div>
          )}
        </div>

        <div className="space-y-2">
          <div className="flex flex-wrap items-center justify-between gap-2">
            <Label>视频描述</Label>
            <div className="flex items-center gap-1.5">
              <Button variant="ghost" size="sm" className="h-7 gap-1.5 text-xs text-primary hover:text-primary" onClick={() => setInspirationOpen(true)}>
                <Sparkles className="h-3 w-3" />
                获取灵感
              </Button>
              {textModelOptions.length > 0 && (
                <Button variant="ghost" size="sm" className="h-7 gap-1.5 text-xs text-primary hover:text-primary" onClick={handleOptimizePrompt} disabled={optimizing || !prompt.trim()}>
                  {optimizing ? <Loader2 className="h-3 w-3 animate-spin" /> : <Wand2 className="h-3 w-3" />}
                  {optimizing ? '优化中...' : '优化提示词'}
                </Button>
              )}
            </div>
          </div>
          <ExpandablePromptTextarea
            title="视频描述"
            placeholder="描述你想要生成的视频画面..."
            rows={4}
            className="h-32 resize-none overflow-y-auto"
            value={prompt}
            onValueChange={setPrompt}
          />
          <div className="flex flex-wrap gap-1.5">
            {VIDEO_STYLES.map(s => (
              <Badge key={s} variant="outline" className="cursor-pointer hover:bg-primary/10 text-xs" onClick={() => setStyle(s)}>{s}</Badge>
            ))}
          </div>
        </div>

        <div className="space-y-2">
          <Label>负面提示词 <span className="text-muted-foreground text-xs">(可选)</span></Label>
          <ExpandablePromptTextarea
            title="负面提示词"
            placeholder="不希望出现的元素..."
            rows={2}
            className="h-24 resize-none overflow-y-auto"
            value={negativePrompt}
            onValueChange={setNegativePrompt}
          />
        </div>

        <div className="grid grid-cols-2 gap-3">
          <div className="space-y-2">
            <Label>画面比例</Label>
            <Select value={aspectRatio} onValueChange={setAspectRatio}>
              <SelectTrigger><SelectValue /></SelectTrigger>
              <SelectContent>
                {VIDEO_ASPECT_RATIOS.map(ar => (
                  <SelectItem key={ar.value} value={ar.value}>{ar.label}</SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-2">
            <Label>视频时长</Label>
            <Select value={duration} onValueChange={setDuration}>
              <SelectTrigger><SelectValue /></SelectTrigger>
              <SelectContent>
                {VIDEO_DURATIONS.map(d => (
                  <SelectItem key={d.value} value={d.value}>{d.label}{membershipEnabled && ` (${d.credits} 积分)`}</SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>

        <div className="space-y-2">
          <Label>镜头运动</Label>
          <Select value={cameraMovement} onValueChange={setCameraMovement}>
            <SelectTrigger><SelectValue /></SelectTrigger>
            <SelectContent>
              {CAMERA_MOVEMENTS.map(c => (
                <SelectItem key={c} value={c}>{c}</SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        <Button className="w-full gap-2" size="lg" onClick={handleGenerate} disabled={!hasModels}>
          {generating ? (<><Plus className="h-4 w-4" />继续提交任务</>) : (<><Sparkles className="h-4 w-4" />生成视频 {membershipEnabled && credits > 0 && `(${credits} 积分)`}</>)}
        </Button>
      </div>

      {/* Right: Results + History */}
      <div className="min-w-0 space-y-4">
        {generating ? (
          <GenerationTaskList tasks={activeTasks} />
        ) : generationError ? (
          <GenerationErrorPanel error={generationError} />
        ) : results.length > 0 ? (
          <div className="space-y-3">
            <div className="flex items-center gap-2 text-sm font-medium"><Video className="h-4 w-4" />生成结果</div>
            {results.map((url, i) => (
              <div key={i} className="liquid-glass-soft overflow-hidden rounded-2xl">
                <video src={url} controls className="w-full" />
                <div className="p-2 flex justify-end gap-2">
                  <Button size="sm" variant="outline" className="gap-1" onClick={() => handleShareToGallery(url)}><Share2 className="h-3.5 w-3.5" />分享</Button>
                  <Button size="sm" variant="outline" className="gap-1" onClick={() => handleDownload(url, i)}><Download className="h-3.5 w-3.5" />下载</Button>
                </div>
              </div>
            ))}
          </div>
        ) : (
          <div className="liquid-glass flex min-h-[300px] flex-col items-center justify-center rounded-2xl border-dashed py-24 text-muted-foreground">
            <Video className="h-14 w-14 mb-3 opacity-20" />
            <p className="text-sm">生成结果将显示在这里</p>
          </div>
        )}

        {videoHistory.length > 0 && (
          <div className="space-y-2">
            <button className="flex items-center gap-2 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors" onClick={() => setShowHistory(!showHistory)}>
              <History className="h-4 w-4" />历史创作 ({videoHistory.length})
              {showHistory ? <ChevronUp className="h-3.5 w-3.5" /> : <ChevronDown className="h-3.5 w-3.5" />}
            </button>
            {showHistory && (
              <div className="grid grid-cols-2 gap-2 max-h-[400px] overflow-y-auto">
                {videoHistory.map(record => (
                  <div
                    key={record.id}
                    className="liquid-glass-soft group relative cursor-pointer overflow-hidden rounded-xl"
                    onClick={() => setSelectedHistoryRecord(record)}
                  >
                    {isPlaceholder(record.url) ? (
                      <div className="w-full aspect-video flex items-center justify-center"><Film className="h-6 w-6 text-muted-foreground/30" /></div>
                    ) : (
                      <div className="w-full aspect-video relative overflow-hidden">
                        <video src={record.url} className="w-full h-full object-cover" preload="metadata" />
                        <div className="absolute inset-0 flex items-center justify-center bg-black/30 opacity-0 group-hover:opacity-100 transition-opacity">
                          <div className="h-8 w-8 rounded-full bg-white/90 flex items-center justify-center">
                            <Film className="h-4 w-4 text-black ml-0.5" />
                          </div>
                        </div>
                      </div>
                    )}
                    <div className="p-1.5"><p className="text-xs text-muted-foreground line-clamp-1">{record.prompt}</p></div>
                  </div>
                ))}
              </div>
            )}
          </div>
        )}
      </div>

      {/* History Detail Dialog */}
      <CreationDetailDialog
        record={selectedHistoryRecord}
        open={!!selectedHistoryRecord}
        onClose={() => setSelectedHistoryRecord(null)}
      />
    </div>
    </>
  );
}
