"use client";

import { useState, useEffect, useRef } from 'react';
import { useRouter } from 'next/navigation';
import { X, Loader2, Upload, ArrowRight, Settings2 } from 'lucide-react';
import { Button } from "@/components/ui/button";
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { DefaultService } from '@/lib/api';
import { CharacterProfile, SceneProfile, PropProfile, Chapter } from '@/types';
import { useModelStore } from '@/lib/store/modelStore';
import React from 'react';

interface CreateProjectWizardProps {
  onClose: () => void;
  mode: 'canvas' | 'script';
}

export type WizardData = {
  projectId: string | null;
  name: string;
  description: string;
  novelText: string;
  selectedStyle: string;
  assets: {
    characters: CharacterProfile[];
    scenes: SceneProfile[];
    props: PropProfile[];
  };
  chapters: Chapter[];
};

export default function CreateProject({ onClose, mode }: CreateProjectWizardProps) {
  const router = useRouter();
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [isReadingFile, setIsReadingFile] = useState(false);
  const draftStorageKey = `project_wizard_draft_${mode}`;
  const isScriptMode = mode === 'script';
  const title = isScriptMode ? '创建新剧本项目' : '创建新画布项目';
  const contentLabel = isScriptMode ? '小说内容 / 剧本素材' : '小说内容';
  
  // Initialize from localStorage if available (Drafts)
  const [data, setData] = useState<WizardData>(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem(draftStorageKey);
      if (saved) return JSON.parse(saved);
    }
    return {
      projectId: null,
      name: '',
      description: '',
      novelText: '',
      selectedStyle: '',
      assets: { characters: [], scenes: [], props: [] },
      chapters: []
    };
  });

  // Save draft on change
  useEffect(() => {
    localStorage.setItem(draftStorageKey, JSON.stringify(data));
  }, [data, draftStorageKey]);

  const updateData = (updates: Partial<WizardData>) => {
    setData(prev => ({ ...prev, ...updates }));
  };

  const readFileContent = (file: File): Promise<string> => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (e) => {
        const buffer = e.target?.result as ArrayBuffer;
        try {
          // Try UTF-8 first with fatal: true to catch encoding errors
          const decoder = new TextDecoder('utf-8', { fatal: true });
          const text = decoder.decode(buffer);
          resolve(text);
        } catch (e) {
          // If UTF-8 fails, try GBK (common for Chinese Windows files)
          try {
            console.log('UTF-8 decoding failed, trying GBK...');
            const decoder = new TextDecoder('gbk');
            const text = decoder.decode(buffer);
            resolve(text);
          } catch (gbkError) {
             // Fallback to non-fatal UTF-8
             const decoder = new TextDecoder('utf-8');
             resolve(decoder.decode(buffer));
          }
        }
      };
      reader.onerror = () => reject(reader.error);
      reader.readAsArrayBuffer(file);
    });
  };

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    if (file.type !== 'text/plain') {
      alert('请上传 .txt 格式的文件');
      return;
    }

    if (file.size > 10 * 1024 * 1024) { // 10MB limit
      alert('文件过大，请上传小于 10MB 的文本文件');
      return;
    }

    setIsReadingFile(true);
    try {
      const text = await readFileContent(file);
      updateData({ novelText: text });
    } catch (err) {
      console.error(err);
      alert('读取文件失败');
    } finally {
      setIsReadingFile(false);
    }
  };

  // Models are loaded globally by ModelInitializer; just read from store here
  const llmModels = useModelStore((s) => s.llmModels);
  const [selectedProvider, setSelectedProvider] = useState<string>('');
  const [selectedModel, setSelectedModel] = useState<string>('');

  const availableModels = React.useMemo(() => Object.values(llmModels), [llmModels]);

  // Default model selection — run only once when llmModels first becomes non-empty
  const hasAutoSelected = useRef(false);
  useEffect(() => {
    if (hasAutoSelected.current || selectedModel) return;
    const models = Object.values(llmModels);
    if (models.length === 0) return;

    const preferred = models.find((m) =>
      m.id.includes('gpt-4') ||
      m.id.includes('plus') ||
      m.id.includes('turbo')
    ) || models[0];

    if (preferred) {
      setSelectedModel(preferred.id);
      setSelectedProvider(preferred.provider);
      hasAutoSelected.current = true;
    }
  }, [llmModels, selectedModel]);

  // Handle model selection
  const handleModelChange = (modelId: string) => {
    setSelectedModel(modelId);
    const model = llmModels[modelId];
    if (model) {
        setSelectedProvider(model.provider);
    }
  };

  const handleFinish = async () => {
    if (!data.name.trim()) return;
    
    setIsLoading(true);
    setError(null);
    
    try {
      let newProjectId;

      if (data.novelText.trim()) {
        const requestBody = {
          name: data.name,
          novelText: data.novelText,
          style: "default",
          model: selectedModel || undefined,
          provider: selectedProvider || undefined,
        };
        const response = isScriptMode
          ? await DefaultService.initializeScriptProjectFromNovel(requestBody)
          : await DefaultService.initializeCanvasProjectFromNovel(requestBody);
        newProjectId = (response as any).data.id;
      } else {
        // Create empty project
        const response = await DefaultService.createProject({
          name: data.name,
          description: data.description || undefined,
          type: isScriptMode ? 'script' : 'canvas'
        });
        newProjectId = (response as any).data.id;
      }
      
      if (!newProjectId) {
        throw new Error("Failed to create project");
      }

      // Clear draft and close immediately
      localStorage.removeItem(draftStorageKey);
      onClose();
      router.push(`/project/${newProjectId}`);
      
    } catch (error: any) {
      console.error("Failed to create project:", error);
      setError(error.message || "创建项目失败");
    } finally {
      setIsLoading(false);
    }
  };

  const handleClose = () => {
    localStorage.removeItem(draftStorageKey);
    onClose();
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm">
      <div className="bg-background border border-border w-[90vw] h-[85vh] rounded-2xl flex flex-col overflow-hidden shadow-2xl">
        
        {/* Header */}
        <div className="h-16 border-b border-border flex items-center justify-between px-6 bg-background/50 backdrop-blur shrink-0">
          <h2 className="text-lg font-semibold text-foreground">{title}</h2>
          <Button variant="ghost" size="icon" onClick={handleClose}>
            <X size={20} />
          </Button>
        </div>

        {/* Content - Two Columns */}
        <div className="flex-1 overflow-hidden flex flex-row">
          
          {/* Left Panel - Settings */}
          <div className="w-[320px] border-r border-border p-6 flex flex-col gap-8 overflow-y-auto bg-background/50">
            <div className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-muted-foreground mb-2">
                  项目名称 <span className="text-red-500">*</span>
                </label>
                <Input
                  type="text"
                  value={data.name}
                  onChange={(e) => updateData({ name: e.target.value.slice(0, 50) })}
                  placeholder="输入项目名称"
                  maxLength={50}
                  className="w-full"
                  autoFocus
                />
                <div className="text-right text-xs text-muted-foreground mt-1">
                  {data.name.length}/50
                </div>
              </div>

              {/* Model Configuration */}
              <div className="space-y-4 pt-4 border-t border-border">
                <div className="flex items-center gap-2 text-sm text-foreground font-medium">
                  <Settings2 className="w-4 h-4" />
                  <span>模型配置</span>
                </div>
                
                <div className="space-y-2">
                  <label className="text-xs text-muted-foreground">选择模型</label>
                  <Select value={selectedModel} onValueChange={handleModelChange}>
                    <SelectTrigger className="w-full">
                      <SelectValue placeholder="选择模型">
                        {selectedModel && llmModels[selectedModel] ? (
                          <div className="flex items-center gap-2">
                            {llmModels[selectedModel].icon && React.createElement(llmModels[selectedModel].icon, { size: 14 })}
                            <span>{llmModels[selectedModel].name || selectedModel}</span>
                          </div>
                        ) : (
                          "选择模型"
                        )}
                      </SelectValue>
                    </SelectTrigger>
                    <SelectContent>
                      {availableModels.map((model) => (
                        <SelectItem key={model.id} value={model.id}>
                          <div className="flex items-center gap-2">
                            {model.icon && React.createElement(model.icon, { size: 14 })}
                            <span>{model.name || model.id}</span>
                          </div>
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </div>
            </div>

            <div className="flex-1" />

            {/* Actions */}
            <div className="space-y-4">
              {error && (
                <div className="p-3 bg-red-500/10 border border-red-500/20 rounded-lg">
                  <p className="text-xs text-red-500">{error}</p>
                </div>
              )}
              
              <Button
                onClick={handleFinish}
                disabled={!data.name.trim() || isLoading}
                className="w-full flex items-center justify-center gap-2 bg-blue-600 hover:bg-blue-500 text-white py-6 rounded-lg font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
              >
                {isLoading ? (
                  <Loader2 className="animate-spin" size={18} />
                ) : (
                  <>
                    {data.novelText.trim() ? (isScriptMode ? "开始改编剧本" : "开始创建画布") : (isScriptMode ? "创建空剧本项目" : "创建空画布项目")}
                    <ArrowRight size={18} />
                  </>
                )}
              </Button>
            </div>
          </div>

          {/* Right Panel - Content */}
          <div className="flex-1 bg-muted/20 flex flex-col overflow-hidden">
             {/* Header with Actions */}
             <div className="px-6 py-4 border-b border-border flex items-center justify-between bg-background/50 shrink-0">
                <div className="flex items-center gap-2">
                   <h3 className="text-sm font-medium text-foreground">{contentLabel}</h3>
                   <Button 
                     variant="outline" 
                     size="sm" 
                     className="h-8 gap-2 ml-2"
                     onClick={() => fileInputRef.current?.click()}
                     disabled={isReadingFile}
                   >
                     {isReadingFile ? <Loader2 className="animate-spin" size={14}/> : <Upload size={14} />}
                     导入文件
                   </Button>
                   <input 
                      ref={fileInputRef}
                      type="file" 
                      accept=".txt" 
                      className="hidden" 
                      onChange={handleFileChange}
                    />
                </div>
                
                {data.novelText && (
                  <span className="text-xs text-muted-foreground">
                    已导入 {data.novelText.length} 字
                  </span>
                )}
             </div>

             {/* Main Content Area - Just the Textarea */}
             <div className="flex-1 p-6 overflow-hidden flex flex-col">
                <Textarea
                  value={data.novelText}
                  onChange={(e) => updateData({ novelText: e.target.value })}
                  placeholder={isScriptMode ? "粘贴小说内容，系统会先通过多 Agent 讨论并生成文字剧本初稿..." : "粘贴小说内容，系统会解析章节、角色、场景、分镜并进入画布项目..."}
                  className="flex-1 bg-background border-border rounded-lg p-6 text-foreground font-mono text-sm focus:outline-none focus:border-blue-500/50 transition-colors resize-none leading-relaxed"
                />
             </div>
          </div>
        </div>
      </div>
    </div>
  );
}
