
import React, { useState, useRef, useEffect } from 'react';
import { CharacterData, LocationData, StyleOption, ReferenceImage, ModelSettings, CharacterVariant } from '../types';
import { generateImageService, constructSpatialPrompt, describeImageContent } from '../services/geminiService';
import { User, MapPin, Upload, Sparkles, RefreshCw, Wand2, X, Shirt, ScanFace, Terminal, Copy, Check, Save, Layers, ArrowLeftRight, History } from 'lucide-react';

interface InteractiveAssetEditorProps {
    type: 'character' | 'location';
    data: CharacterData | LocationData;
    styleOption: StyleOption;
    onUpdate: (data: CharacterData | LocationData) => void;
    modelSettings: ModelSettings;
}

const InteractiveAssetEditor: React.FC<InteractiveAssetEditorProps> = ({ type, data, styleOption, onUpdate, modelSettings }) => {
    const [isGenerating, setIsGenerating] = useState(false);
    const [description, setDescription] = useState(data.naturalDescription);
    const [constructedPrompt, setConstructedPrompt] = useState('');
    const [isCopied, setIsCopied] = useState(false);
    const [isSavingVariant, setIsSavingVariant] = useState(false);
    const [variantName, setVariantName] = useState('');
    const [isAnalyzingImage, setIsAnalyzingImage] = useState(false);

    const fileInputRef = useRef<HTMLInputElement>(null);
    const overrideInputRef = useRef<HTMLInputElement>(null);
    const [draggedId, setDraggedId] = useState<string | null>(null);
    const canvasRef = useRef<HTMLDivElement>(null);
    
    const hasMasterImage = !!(data as any).masterImage;
    const variants = (type === 'character') ? (data as CharacterData).variants || [] : [];

    const getSemanticPosition = (x: number, y: number): string => {
        let v = "center";
        let h = "center";
        if (y < 33) v = "top"; else if (y > 66) v = "bottom";
        if (x < 33) h = "left"; else if (x > 66) h = "right";
        if (v === "center" && h === "center") return "center";
        return `${v}-${h}`;
    };

    useEffect(() => {
        const prompt = constructSpatialPrompt(
            description, 
            styleOption, 
            data.referenceImages, 
            type,
            hasMasterImage,
            modelSettings.googleApiKey
        );
        setConstructedPrompt(prompt);
    }, [description, data.referenceImages, styleOption, type, hasMasterImage, modelSettings.googleApiKey]);

    const handleGenerate = async () => {
        if (!modelSettings.googleApiKey) {
            alert("請先輸入 Google API Key");
            return;
        }
        setIsGenerating(true);
        try {
            const finalPrompt = constructSpatialPrompt(
                description, 
                styleOption, 
                data.referenceImages,
                type,
                hasMasterImage,
                modelSettings.googleApiKey
            );
            // IF hasMasterImage, use it as BASE for variation
            const baseImage = hasMasterImage ? (data as any).masterImage : undefined;
            
            const imgUrl = await generateImageService(
                finalPrompt, 
                styleOption, 
                modelSettings.imageModel,
                type, 
                baseImage, 
                data.referenceImages,
                modelSettings.googleApiKey,
                modelSettings.devMode || false
            );
            onUpdate({ ...data, naturalDescription: description, masterImage: imgUrl } as any);
        } catch (e: any) {
            console.error(e);
            alert(`生成失敗: ${e.message}`);
        } finally {
            setIsGenerating(false);
        }
    };

    const handleCopyPrompt = () => {
        navigator.clipboard.writeText(constructedPrompt);
        setIsCopied(true);
        setTimeout(() => setIsCopied(false), 2000);
    };

    // --- REVERSE ENGINEERING ---
    const handleOverrideUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
        const file = e.target.files?.[0];
        if (!file) return;
        if (!modelSettings.googleApiKey) {
            alert("請先輸入 Google API Key");
            return;
        }
        
        setIsAnalyzingImage(true);
        const reader = new FileReader();
        reader.onload = async (event) => {
            if (event.target?.result) {
                const base64 = event.target.result as string;
                try {
                    // 1. Analyze image to get prompt
                    const analysis = await describeImageContent(base64, modelSettings.textModel, modelSettings.googleApiKey);
                    
                    // 2. Update Asset
                    setDescription(analysis);
                    onUpdate({ 
                        ...data, 
                        naturalDescription: analysis,
                        masterImage: base64 // Set uploaded image as master
                    } as any);
                    alert("圖片解析完成！Prompt 與圖片已更新。");
                } catch (err: any) {
                    alert(`解析失敗: ${err.message}`);
                } finally {
                    setIsAnalyzingImage(false);
                }
            }
        };
        reader.readAsDataURL(file);
        e.target.value = '';
    };

    // --- VARIANT MANAGEMENT ---
    const handleSaveVariant = () => {
        if (!variantName) return;
        const currentMaster = (data as any).masterImage;
        if (!currentMaster) return;

        const newVariant: CharacterVariant = {
            id: Date.now().toString(),
            name: variantName,
            imageUrl: currentMaster
        };

        const updatedVariants = [...variants, newVariant];
        onUpdate({ ...data, variants: updatedVariants } as any);
        setIsSavingVariant(false);
        setVariantName('');
    };

    const handleSelectVariant = (variant: CharacterVariant) => {
        onUpdate({ ...data, masterImage: variant.imageUrl } as any);
    };

    const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
        const file = e.target.files?.[0];
        if (!file) return;
        const reader = new FileReader();
        reader.onload = (event) => {
            if (event.target?.result) {
                const newRef: ReferenceImage = {
                    id: Date.now().toString(),
                    url: event.target.result as string,
                    x: 50, y: 50, width: 100, zIndex: data.referenceImages.length + 1,
                    semanticPosition: 'center',
                    usage: hasMasterImage ? 'accessory' : 'face'
                };
                onUpdate({ ...data, referenceImages: [...data.referenceImages, newRef] });
            }
        };
        reader.readAsDataURL(file);
        e.target.value = '';
    };

    const handleRemoveRef = (id: string, e: React.MouseEvent) => {
        e.stopPropagation(); 
        onUpdate({ ...data, referenceImages: data.referenceImages.filter(r => r.id !== id) });
    }

    const handleMouseDown = (e: React.MouseEvent, id: string) => {
        e.preventDefault(); e.stopPropagation(); setDraggedId(id);
    };

    const handleMouseMove = (e: React.MouseEvent) => {
        if (!draggedId || !canvasRef.current) return;
        const rect = canvasRef.current.getBoundingClientRect();
        const x = Math.max(0, Math.min(100, ((e.clientX - rect.left) / rect.width) * 100));
        const y = Math.max(0, Math.min(100, ((e.clientY - rect.top) / rect.height) * 100));
        const updatedRefs = data.referenceImages.map(img => img.id === draggedId ? { ...img, x, y, semanticPosition: getSemanticPosition(x, y) } : img);
        onUpdate({ ...data, referenceImages: updatedRefs });
    };

    const masterImg = (data as any).masterImage;

    return (
        <div className="glass-card rounded-3xl overflow-hidden flex flex-col lg:flex-row min-h-[750px]">
            {/* LEFT: Canvas */}
            <div 
                ref={canvasRef}
                className="relative w-full lg:w-7/12 bg-black/30 overflow-hidden cursor-crosshair select-none flex items-center justify-center backdrop-blur-sm"
                onMouseMove={handleMouseMove}
                onMouseUp={() => setDraggedId(null)}
                onMouseLeave={() => setDraggedId(null)}
            >
                <div className="absolute inset-0 bg-grid opacity-20 pointer-events-none" />
                <div className="absolute top-6 left-6 z-10 flex flex-col gap-2">
                     <div className={`glass-panel px-4 py-2 rounded-full font-bold flex items-center gap-2 text-xs uppercase tracking-wider ${hasMasterImage ? 'text-purple-300 border-purple-500/30' : 'text-amber-300 border-amber-500/30'}`}>
                        {hasMasterImage ? <><History className="w-4 h-4" /> 變體模式 (Variation)</> : <><ScanFace className="w-4 h-4" /> 原型生成 (Base)</>}
                    </div>
                </div>

                {masterImg ? (
                    <img src={masterImg} className="absolute inset-0 w-full h-full object-contain z-0" alt="Master Asset" />
                ) : (
                    <div className="text-zinc-600 flex flex-col items-center">
                        <User className="w-24 h-24 mb-4 opacity-20" />
                        <span className="text-sm font-mono opacity-50">拖曳編輯區</span>
                    </div>
                )}

                {data.referenceImages.map((ref) => (
                    <div
                        key={ref.id}
                        onMouseDown={(e) => handleMouseDown(e, ref.id)}
                        className={`absolute cursor-move border-2 rounded-lg overflow-hidden shadow-2xl transition-transform ${draggedId === ref.id ? 'z-50 scale-105 border-white' : ref.usage === 'face' ? 'border-amber-500/50' : 'border-indigo-500/50'}`}
                        style={{ left: `${ref.x}%`, top: `${ref.y}%`, width: '120px', transform: 'translate(-50%, -50%)', zIndex: ref.zIndex }}
                    >
                        <div className="relative group">
                            <img src={ref.url} className="w-full h-auto bg-black pointer-events-none" />
                            <div className={`absolute top-0 left-0 px-2 py-0.5 text-[9px] font-bold text-black uppercase ${ref.usage === 'face' ? 'bg-amber-500' : 'bg-indigo-500 text-white'}`}>{ref.usage}</div>
                            <button onClick={(e) => handleRemoveRef(ref.id, e)} className="absolute -top-2 -right-2 bg-red-500 text-white rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity"><X className="w-3 h-3" /></button>
                        </div>
                    </div>
                ))}
            </div>

            {/* RIGHT: Control Panel */}
            <div className="w-full lg:w-5/12 bg-black/20 flex flex-col border-l border-white/5">
                <div className="p-6 border-b border-white/5">
                    <div className="flex items-center justify-between">
                         <div className="flex items-center gap-4">
                             <div className={`p-2 rounded-lg ${type === 'character' ? 'bg-indigo-500/20 text-indigo-400' : 'bg-emerald-500/20 text-emerald-400'}`}>
                                 {type === 'character' ? <User className="w-6 h-6" /> : <MapPin className="w-6 h-6" />}
                             </div>
                             <div>
                                 <input
                                     type="text"
                                     value={data.name}
                                     onChange={(e) => onUpdate({ ...data, name: e.target.value } as any)}
                                     className="font-bold text-white text-2xl tracking-tight bg-transparent border-none outline-none focus:outline-none focus:ring-0 p-0 w-full"
                                     style={{ borderBottom: '1px solid transparent' }}
                                     onFocus={(e) => e.target.style.borderBottomColor = 'rgba(99, 102, 241, 0.5)'}
                                     onBlur={(e) => e.target.style.borderBottomColor = 'transparent'}
                                 />
                             </div>
                         </div>
                         <div className="flex gap-2">
                             <button onClick={() => overrideInputRef.current?.click()} className="p-2 text-zinc-400 hover:text-white bg-white/5 rounded-lg border border-white/5 hover:border-white/20 text-xs flex items-center gap-1" title="上傳圖片並逆向分析 Prompt">
                                {isAnalyzingImage ? <RefreshCw className="w-4 h-4 animate-spin" /> : <ArrowLeftRight className="w-4 h-4" />}
                                <span className="hidden sm:inline">逆向工程</span>
                             </button>
                             <input type="file" ref={overrideInputRef} className="hidden" accept="image/*" onChange={handleOverrideUpload} />
                         </div>
                    </div>
                </div>

                <div className="flex-1 overflow-y-auto p-6 space-y-8">
                    {/* VARIANTS SECTION (Only for Characters) */}
                    {type === 'character' && (
                        <div className="glass-panel rounded-xl p-4">
                            <div className="flex justify-between items-center mb-3">
                                <label className="text-xs font-bold text-zinc-400 uppercase tracking-wider flex items-center gap-2">
                                    <Layers className="w-3 h-3" /> 多重造型庫 (Variants)
                                </label>
                                <button 
                                    onClick={() => setIsSavingVariant(true)}
                                    className="text-[10px] bg-indigo-500/20 text-indigo-300 px-2 py-1 rounded border border-indigo-500/30 hover:bg-indigo-500/40"
                                >
                                    + 儲存當前造型
                                </button>
                            </div>
                            
                            {isSavingVariant && (
                                <div className="flex gap-2 mb-3">
                                    <input 
                                        type="text" 
                                        value={variantName}
                                        onChange={(e) => setVariantName(e.target.value)}
                                        placeholder="輸入造型名稱 (如: 睡衣)"
                                        className="glass-input w-full rounded p-1 text-xs"
                                    />
                                    <button onClick={handleSaveVariant} className="text-xs bg-emerald-500/20 text-emerald-400 px-2 rounded"><Save className="w-3 h-3" /></button>
                                </div>
                            )}

                            <div className="flex gap-2 overflow-x-auto pb-2">
                                <div 
                                    onClick={() => onUpdate({...data, masterImage: (data as any).masterImage} as any)} 
                                    className="w-16 h-16 shrink-0 rounded-lg border border-zinc-700 bg-black cursor-pointer overflow-hidden relative"
                                    title="Current Workspace"
                                >
                                    {masterImg && <img src={masterImg} className="w-full h-full object-cover" />}
                                    <div className="absolute inset-x-0 bottom-0 bg-indigo-600/80 text-[8px] text-white text-center py-0.5 truncate">當前</div>
                                </div>
                                {variants.map(v => (
                                    <div 
                                        key={v.id} 
                                        onClick={() => handleSelectVariant(v)}
                                        className="w-16 h-16 shrink-0 rounded-lg border border-zinc-700 bg-black cursor-pointer overflow-hidden relative group"
                                        title={v.name}
                                    >
                                        <img src={v.imageUrl} className="w-full h-full object-cover" />
                                        <div className="absolute inset-x-0 bottom-0 bg-black/60 text-[8px] text-white text-center py-0.5 truncate">{v.name}</div>
                                    </div>
                                ))}
                            </div>
                        </div>
                    )}

                    <div className="space-y-3">
                        <label className="flex items-center gap-2 text-xs font-bold text-zinc-400 uppercase tracking-wider">
                            <Sparkles className="w-3 h-3 text-indigo-400" /> 
                            {hasMasterImage ? '變體描述 (Variation Instruction)' : '自然語言描述 (Description)'}
                        </label>
                        <textarea 
                            className="glass-input w-full rounded-xl p-4 text-sm h-24 resize-none"
                            value={description} onChange={(e) => setDescription(e.target.value)}
                            placeholder={hasMasterImage ? "請描述要如何修改這張圖片 (例如: 變成生氣的表情, 改成敬禮姿勢)..." : "請描述角色的外貌特徵、服裝與氣質..."}
                        />
                    </div>

                    <div className="space-y-3">
                        <label className="flex items-center gap-2 text-xs font-bold text-zinc-400 uppercase tracking-wider">
                            {hasMasterImage ? '添加配件 (Add Accessories)' : '添加參考圖 (Add References)'}
                        </label>
                        <div onClick={() => fileInputRef.current?.click()} className={`glass-input border-dashed rounded-xl p-6 cursor-pointer text-center group hover:bg-white/5 ${hasMasterImage ? 'hover:border-purple-500' : 'hover:border-amber-500'}`}>
                            <input type="file" ref={fileInputRef} className="hidden" accept="image/*" onChange={handleFileUpload} />
                            <div className="flex flex-col items-center gap-3 text-zinc-500 group-hover:text-white transition-colors">
                                <Upload className="w-6 h-6" />
                                <span className="text-xs font-medium">{hasMasterImage ? '上傳配件 (維持基底)' : '上傳臉部/風格參考'}</span>
                            </div>
                        </div>
                    </div>

                    <div className="glass-panel rounded-xl p-4 font-mono text-[10px] text-zinc-500 relative group">
                        <div className="flex items-center gap-2 mb-2 text-indigo-400 uppercase tracking-wider font-bold">
                            <Terminal className="w-3 h-3" /> 提示詞檢視器
                            <button 
                                onClick={handleCopyPrompt} 
                                className="ml-auto hover:text-white text-zinc-500 transition-colors p-1 rounded hover:bg-white/10"
                                title="複製提示詞"
                            >
                                {isCopied ? <Check className="w-3 h-3 text-emerald-400" /> : <Copy className="w-3 h-3" />}
                            </button>
                        </div>
                        <div className="opacity-70 max-h-32 overflow-y-auto break-all">{constructedPrompt || '等待輸入中...'}</div>
                    </div>
                </div>

                <div className="p-6 border-t border-white/5">
                    <button 
                        onClick={handleGenerate} disabled={isGenerating}
                        className={`glass-btn w-full py-4 rounded-xl font-bold flex items-center justify-center gap-3 ${isGenerating ? 'opacity-50' : hasMasterImage ? 'bg-purple-600/20 border-purple-500/50 hover:bg-purple-600/40 text-purple-200' : 'hover:bg-indigo-600/30 hover:border-indigo-500/50 text-white'}`}
                    >
                        {isGenerating ? <RefreshCw className="w-5 h-5 animate-spin" /> : hasMasterImage ? <Sparkles className="w-5 h-5" /> : <Wand2 className="w-5 h-5" />}
                        <span>{isGenerating ? '處理中...' : hasMasterImage ? '基於原圖生成變體 (Generate Variation)' : '生成原型 (Generate Base)'}</span>
                    </button>
                    {hasMasterImage && (
                        <button onClick={() => { onUpdate({ ...data, masterImage: undefined } as any); }} className="w-full mt-3 py-2 text-xs text-zinc-500 hover:text-red-400 uppercase font-bold">重置 (Reset)</button>
                    )}
                </div>
            </div>
        </div>
    )
}

export default InteractiveAssetEditor;
