import { useState, useEffect, useMemo } from "react"
import { 
    useAnalysisTemplates, 
    useAnalysisTemplate,
    useSaveAnalysisTemplate, 
    useDeleteAnalysisTemplate,
    useLlmProviders 
} from "@/hooks/useConfig"
import { AnalysisTemplateSet, AnalysisModuleConfig } from "@/types/config"
import { schemas } from "@/api/schema.gen"
import { z } from "zod"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Badge } from "@/components/ui/badge"
import { ArrowRight, Box, Layers, Save, Plus, Pencil, Trash2, ChevronDown, ChevronUp } from "lucide-react"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Label } from "@/components/ui/label"
import { useToast } from "@/hooks/use-toast"

export function TemplateTab() {
  const { data: templates, isLoading } = useAnalysisTemplates();
  const saveTemplate = useSaveAnalysisTemplate();
  const deleteTemplate = useDeleteAnalysisTemplate();
  const { toast } = useToast();
  const [selectedId, setSelectedId] = useState<string | null>(null);

  // Auto select first if none selected
  useEffect(() => {
    if (templates && !selectedId && templates.length > 0) {
      setSelectedId(templates[0].id);
    }
  }, [templates, selectedId]);

  if (isLoading) return <div>Loading templates...</div>;

  const handleCreateTemplate = () => {
      const newId = crypto.randomUUID();
      const newTemplate: AnalysisTemplateSet = {
          name: "New Template",
          modules: {}
      };
      
      saveTemplate.mutate({ id: newId, template: newTemplate }, {
          onSuccess: () => {
              toast({ title: "Success", description: "Template created" });
              setSelectedId(newId);
          },
          onError: () => toast({ title: "Error", description: "Failed to create template", type: "error" })
      });
  }

  const handleDeleteTemplate = (id: string) => {
      deleteTemplate.mutate(id, {
          onSuccess: () => {
              toast({ title: "Success", description: "Template deleted" });
              if (selectedId === id) setSelectedId(null);
          },
          onError: () => toast({ title: "Error", description: "Failed to delete template", type: "error" })
      });
  }

  return (
      <div className="flex h-[600px] border rounded-md overflow-hidden">
          {/* Sidebar List */}
          <div className="w-[250px] border-r bg-muted/10 flex flex-col">
              <div className="p-4 border-b">
                  <h4 className="font-medium mb-1">模板列表</h4>
                  <p className="text-xs text-muted-foreground">选择一个分析流程模板进行编辑。</p>
              </div>
              <ScrollArea className="flex-1">
                  <div className="p-2 space-y-1">
                      {templates && templates.map((t) => (
                          <div key={t.id} className="group relative flex items-center">
                          <button
                              onClick={() => setSelectedId(t.id)}
                              className={`w-full text-left px-3 py-2 rounded-md text-sm transition-colors flex items-center justify-between ${
                                  selectedId === t.id ? "bg-accent text-accent-foreground font-medium" : "hover:bg-muted"
                              }`}
                          >
                                  <span className="truncate pr-6">{t.name}</span>
                              {selectedId === t.id && <ArrowRight className="h-3 w-3 opacity-50" />}
                          </button>
                              {/* Delete button visible on hover */}
                              <button 
                                  onClick={(e) => { e.stopPropagation(); handleDeleteTemplate(t.id); }}
                                  className="absolute right-2 top-2 hidden group-hover:block text-muted-foreground hover:text-destructive"
                              >
                                  <Trash2 className="h-3 w-3" />
                              </button>
                          </div>
                      ))}
                  </div>
              </ScrollArea>
          <div className="p-3 border-t bg-background">
              <Button size="sm" variant="outline" className="w-full" onClick={handleCreateTemplate}>
                  <Plus className="mr-2 h-4 w-4" /> 新建模板
              </Button>
          </div>
      </div>

      {/* Main Content */}
      <div className="flex-1 bg-background flex flex-col">
          {selectedId ? (
              <TemplateDetailWrapper 
                  key={selectedId}
                  templateId={selectedId} 
              />
          ) : (
              <div className="flex-1 flex items-center justify-center text-muted-foreground">
                  {templates && templates.length === 0 ? "No templates found. Create one." : "Select a template"}
              </div>
          )}
      </div>
    </div>
  )
}

function TemplateDetailWrapper({ templateId }: { templateId: string }) {
    const { data: template, isLoading, isError } = useAnalysisTemplate(templateId);
    const saveTemplate = useSaveAnalysisTemplate();
    const { toast } = useToast();

    if (isLoading) return <div className="flex items-center justify-center h-full">Loading details...</div>;
    if (isError || !template) return <div className="flex items-center justify-center h-full text-destructive">Error loading template</div>;

    const handleSave = (updatedTemplate: AnalysisTemplateSet) => {
        saveTemplate.mutate({ id: templateId, template: updatedTemplate }, {
            onSuccess: () => toast({ title: "Success", description: "Template saved" }),
            onError: () => toast({ title: "Error", description: "Failed to save template", type: "error" })
        });
    };

    return (
        <TemplateDetailView 
            template={template} 
            onSave={handleSave} 
            isSaving={saveTemplate.isPending} 
        />
    );
}

function TemplateDetailView({ template, onSave, isSaving }: { template: AnalysisTemplateSet, onSave: (t: AnalysisTemplateSet) => void, isSaving: boolean }) {
    const [localTemplate, setLocalTemplate] = useState(template);
    const [isDirty, setIsDirty] = useState(false);
    const [isRenaming, setIsRenaming] = useState(false);
    const [newName, setNewName] = useState(template.name);

    useEffect(() => {
        setLocalTemplate(template);
        setNewName(template.name);
        setIsDirty(false);
    }, [template]);

    const handleRename = () => {
        setLocalTemplate((prev: AnalysisTemplateSet) => ({ ...prev, name: newName }));
        setIsRenaming(false);
        setIsDirty(true);
    }

    const handleAddModule = () => {
        const newModuleId = "module_" + Math.random().toString(36).substring(2, 9);
        const newModule: AnalysisModuleConfig = {
            name: "New Analysis Module",
            analysis_prompt: "Analyze the following financial data:\n\n{{data}}\n\nProvide insights on...",
            dependencies: [],
            context_selector: { Manual: { rules: [] } },
            llm_config: { model_id: "" },
            output_type: "markdown"
        };
        
        setLocalTemplate((prev: AnalysisTemplateSet) => ({
            ...prev,
            modules: {
                ...prev.modules,
                [newModuleId]: newModule
            }
        }));
        setIsDirty(true);
    }

    const handleDeleteModule = (moduleId: string) => {
        setLocalTemplate((prev: AnalysisTemplateSet) => {
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            const { [moduleId]: removed, ...rest } = prev.modules as Record<string, AnalysisModuleConfig>;
            return { ...prev, modules: rest };
        });
        setIsDirty(true);
    }

    const handleUpdateModule = (moduleId: string, updatedModule: AnalysisModuleConfig) => {
        setLocalTemplate((prev: AnalysisTemplateSet) => ({
            ...prev,
            modules: {
                ...prev.modules,
                [moduleId]: updatedModule
            }
        }));
        setIsDirty(true);
    }

    return (
        <div className="flex flex-col h-full">
            <div className="p-6 border-b">
                <div className="flex justify-between items-start">
                    <div className="flex-1 mr-4">
                        {isRenaming ? (
                            <div className="flex items-center gap-2">
                                <Input 
                                    value={newName} 
                                    onChange={(e) => setNewName(e.target.value)} 
                                    className="h-8 text-lg font-bold"
                                />
                                <Button size="sm" onClick={handleRename}>OK</Button>
                                <Button size="sm" variant="ghost" onClick={() => setIsRenaming(false)}>Cancel</Button>
                            </div>
                        ) : (
                            <div className="flex items-center gap-2 group">
                                <h2 className="text-2xl font-bold tracking-tight">{localTemplate.name}</h2>
                                <Button variant="ghost" size="icon" className="h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity" onClick={() => setIsRenaming(true)}>
                                    <Pencil className="h-3 w-3" />
                                </Button>
                            </div>
                        )}
                        <p className="text-muted-foreground mt-1">
                            包含 {Object.keys(localTemplate.modules).length} 个分析模块。
                        </p>
                    </div>
                    <div className="space-x-2">
                        <Button disabled={!isDirty || isSaving} onClick={() => onSave(localTemplate)}>
                            {isSaving ? <span className="flex items-center"><span className="animate-spin mr-2">⏳</span>Saving...</span> : <span className="flex items-center"><Save className="mr-2 h-4 w-4"/>保存更改</span>}
                        </Button>
                    </div>
                </div>
            </div>
            
            <ScrollArea className="flex-1 p-6">
                <div className="grid gap-6">
                    <div className="flex items-center justify-between">
                        <h3 className="text-lg font-medium flex items-center">
                            <Layers className="mr-2 h-5 w-5" />
                            模块流水线 (Pipeline)
                        </h3>
                        <Button size="sm" variant="secondary" onClick={handleAddModule}>+ 添加模块</Button>
                    </div>
                    
                    {Object.entries(localTemplate.modules).length === 0 ? (
                         <div className="text-center py-10 text-muted-foreground bg-muted/20 rounded-lg border border-dashed">
                            No modules configured. Add one to start.
                         </div>
                    ) : (
                        Object.entries(localTemplate.modules).map(([moduleId, module]) => (
                            <ModuleCard 
                                key={moduleId} 
                                id={moduleId} 
                                module={module} 
                                availableModules={Object.keys(localTemplate.modules).filter(k => k !== moduleId)}
                                allModules={localTemplate.modules}
                                onDelete={() => handleDeleteModule(moduleId)}
                                onUpdate={(m) => handleUpdateModule(moduleId, m)}
                            />
                        ))
                    )}
                </div>
            </ScrollArea>
        </div>
    )
}

function ModuleCard({ id, module, availableModules, allModules, onDelete, onUpdate }: { 
    id: string, 
    module: AnalysisModuleConfig, 
    availableModules: string[],
    allModules: Record<string, AnalysisModuleConfig>,
    onDelete: () => void,
    onUpdate: (m: AnalysisModuleConfig) => void
}) {
    const [isExpanded, setIsExpanded] = useState(false);
    const { data: providers } = useLlmProviders();
    
    // Flatten models for select
    const allModels: { providerId: string, modelId: string, name: string }[] = [];
    const seenKeys = new Set<string>();

    if (providers) {
        Object.entries(providers as Record<string, any>).forEach(([pid, p]) => {
            (p as { models: { model_id: string, name?: string | null }[] }).models.forEach((m) => {
                const uniqueKey = m.model_id;
                if (!seenKeys.has(uniqueKey)) {
                    seenKeys.add(uniqueKey);
                    allModels.push({
                        providerId: pid,
                        modelId: m.model_id,
                        name: `${p.name} - ${m.name || m.model_id}`
                    });
                }
            });
        });
    }

    const handleModelChange = (mid: string) => {
        onUpdate({ 
            ...module, 
            llm_config: { ...module.llm_config, model_id: mid } 
        });
    }

    const currentModelId = module.llm_config?.model_id;

    // Dynamically derive modes from Zod Schema
    const availableSelectionModes = useMemo(() => {
        if (schemas.SelectionMode instanceof z.ZodUnion) {
            return schemas.SelectionMode.options.map((opt: any) => {
                // Each option is ZodObject or similar, we extract the first key of the shape
                // shape is available on ZodObject
                const shape = opt.shape || (opt._def && opt._def.shape && opt._def.shape());
                if (shape) {
                    return Object.keys(shape)[0];
                }
                return "Unknown";
            }).filter(Boolean) as string[];
        }
        return ["Manual", "Auto", "Hybrid"]; // Fallback if schema introspection fails
    }, []);

    const currentMode = Object.keys(module.context_selector)[0];

    const handleModeChange = (newMode: string) => {
        // Initialize default structure based on mode
        // Note: While modes are dynamic, default init still requires some knowledge or a more complex generator
        // For now, we use a robust switch, but the keys come from the schema in the UI.
        if (newMode === 'Manual') {
            onUpdate({ ...module, context_selector: { Manual: { rules: [] } } });
        } else if (newMode === 'Auto') {
            onUpdate({ ...module, context_selector: { Auto: { llm_config: null } } });
        } else if (newMode === 'Hybrid') {
            onUpdate({ ...module, context_selector: { Hybrid: { selection_prompt: "", llm_config: null } } });
        }
    }

    // Helper to get manual rules
    const getManualRules = () => {
        if ('Manual' in module.context_selector) {
            return module.context_selector.Manual.rules.join('\n');
        }
        return "";
    }

    const handleRulesChange = (text: string) => {
        const rules = text.split('\n').filter(line => line.trim() !== "");
        onUpdate({
            ...module,
            context_selector: { Manual: { rules } }
        });
    }

    const getSelectionPrompt = () => {
        if ('Hybrid' in module.context_selector) {
            return module.context_selector.Hybrid.selection_prompt;
        }
        return "";
    }

    const handleSelectionPromptChange = (text: string) => {
        if ('Hybrid' in module.context_selector) {
            onUpdate({
                ...module,
                context_selector: { 
                    Hybrid: { 
                        ...module.context_selector.Hybrid,
                        selection_prompt: text 
                    } 
                }
            });
        }
    }

    const getSelectorModelId = () => {
        if ('Auto' in module.context_selector) {
            return module.context_selector.Auto.llm_config?.model_id;
        }
        if ('Hybrid' in module.context_selector) {
            return module.context_selector.Hybrid.llm_config?.model_id;
        }
        return undefined;
    }

    const handleSelectorModelChange = (mid: string) => {
        const llmConfig = { model_id: mid };
        if (currentMode === 'Auto') {
             onUpdate({
                ...module,
                context_selector: { Auto: { llm_config: llmConfig } }
            });
        } else if (currentMode === 'Hybrid') {
            if ('Hybrid' in module.context_selector) {
                onUpdate({
                    ...module,
                    context_selector: { 
                        Hybrid: { 
                            ...module.context_selector.Hybrid,
                            llm_config: llmConfig
                        } 
                    }
                });
            } else {
                // Handle edge case where currentMode is Hybrid but selector state not yet updated
                // This usually shouldn't happen if useEffect syncs correctly, but safety first
                 onUpdate({
                    ...module,
                    context_selector: { 
                        Hybrid: { 
                            selection_prompt: "",
                            llm_config: llmConfig
                        } 
                    }
                });
            }
        }
    }

    const toggleDependency = (depId: string) => {
        const newDeps = module.dependencies.includes(depId)
            ? module.dependencies.filter((d: string) => d !== depId)
            : [...module.dependencies, depId];
        onUpdate({ ...module, dependencies: newDeps });
    }

    return (
        <Card className={isExpanded ? "border-primary/50" : ""}>
            <CardHeader className="pb-3 cursor-pointer hover:bg-muted/5 transition-colors" onClick={() => setIsExpanded(!isExpanded)}>
                <div className="flex justify-between items-start">
                    <div className="flex items-center gap-2">
                        <div className="bg-primary/10 p-2 rounded-md text-primary">
                            <Box className="h-4 w-4" />
                        </div>
                        <div>
                            <CardTitle className="text-base flex items-center gap-2">
                                {module.name}
                                <span className="text-xs font-normal text-muted-foreground">({id})</span>
                            </CardTitle>
                            <CardDescription className="hidden"></CardDescription>
                            <div className="flex items-center gap-2 mt-1">
                                <Badge variant="outline" className="font-normal text-[10px] h-5">
                                    {currentModelId || "No Model"}
                                </Badge>
                                {module.dependencies.length > 0 && (
                                    <span className="text-[10px] text-muted-foreground">
                                        Depends on: {module.dependencies.length}
                                    </span>
                                )}
                            </div>
                        </div>
                    </div>
                    <div className="flex items-center gap-2">
                         <Button variant="ghost" size="icon" className="h-8 w-8">
                            {isExpanded ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
                        </Button>
                        <Button variant="ghost" size="icon" className="h-8 w-8 text-muted-foreground hover:text-destructive z-10" onClick={(e) => { e.stopPropagation(); onDelete(); }}>
                            <Trash2 className="h-4 w-4" />
                        </Button>
                    </div>
                </div>
            </CardHeader>
            
            {isExpanded && (
                <CardContent className="border-t pt-4 space-y-4 animate-in slide-in-from-top-2 duration-200">
                    <div className="grid gap-4 md:grid-cols-2">
                        <div className="space-y-2">
                            <Label>Module Name</Label>
                            <Input value={module.name} onChange={(e) => onUpdate({...module, name: e.target.value})} />
                        </div>
                        <div className="space-y-2">
                            <Label>Model</Label>
                            <Select value={currentModelId || ""} onValueChange={handleModelChange}>
                                <SelectTrigger>
                                    <SelectValue placeholder="Select Model" />
                                </SelectTrigger>
                                <SelectContent>
                                    {allModels.length > 0 ? (
                                        allModels.map(m => (
                                            <SelectItem key={m.modelId} value={m.modelId}>
                                                {m.name}
                                            </SelectItem>
                                        ))
                                    ) : (
                                        <SelectItem value="no_models" disabled>
                                            No models found
                                        </SelectItem>
                                    )}
                                </SelectContent>
                            </Select>
                        </div>
                    </div>

                    <div className="space-y-2 border p-4 rounded-md bg-muted/5">
                        <div className="flex items-center justify-between">
                            <Label>Context Selection Mode</Label>
                            <Select value={currentMode} onValueChange={(v) => handleModeChange(v)}>
                                <SelectTrigger className="w-[180px]">
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    {availableSelectionModes.map(m => (
                                        <SelectItem key={m} value={m}>{m}</SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>

                        {currentMode === 'Manual' && (
                            <div className="space-y-2 mt-4">
                                <Label className="text-xs">Glob Patterns</Label>
                                <Textarea 
                                    value={getManualRules()} 
                                    onChange={(e) => handleRulesChange(e.target.value)}
                                    className="font-mono text-xs min-h-[80px]" 
                                    placeholder="raw/tushare/{{symbol}}/*.json"
                                />
                                <p className="text-[10px] text-muted-foreground">
                                    One rule per line. Use <code>{"{{symbol}}"}</code> as placeholder.
                                </p>
                            </div>
                        )}

                        {currentMode === 'Auto' && (
                            <div className="space-y-2 mt-4">
                                <Label className="text-xs">Selector Model</Label>
                                <Select value={getSelectorModelId() || ""} onValueChange={handleSelectorModelChange}>
                                    <SelectTrigger>
                                        <SelectValue placeholder="Select Model for Selection" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {allModels.map(m => (
                                            <SelectItem key={m.modelId} value={m.modelId}>
                                                {m.name}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                <p className="text-[10px] text-muted-foreground">
                                    The LLM will automatically select relevant files based on the directory tree.
                                </p>
                            </div>
                        )}

                        {currentMode === 'Hybrid' && (
                            <div className="space-y-4 mt-4">
                                <div className="space-y-2">
                                    <Label className="text-xs">Selector Model</Label>
                                    <Select value={getSelectorModelId() || ""} onValueChange={handleSelectorModelChange}>
                                        <SelectTrigger>
                                            <SelectValue placeholder="Select Model for Selection" />
                                        </SelectTrigger>
                                        <SelectContent>
                                            {allModels.map(m => (
                                                <SelectItem key={m.modelId} value={m.modelId}>
                                                    {m.name}
                                                </SelectItem>
                                            ))}
                                        </SelectContent>
                                    </Select>
                                </div>
                                <div className="space-y-2">
                                    <Label className="text-xs">Selection Prompt</Label>
                                    <Textarea 
                                        value={getSelectionPrompt()} 
                                        onChange={(e) => handleSelectionPromptChange(e.target.value)}
                                        className="font-mono text-xs min-h-[80px]" 
                                        placeholder="Find all financial statements from 2024..."
                                    />
                                    <p className="text-[10px] text-muted-foreground">
                                        Describe what files you need. The LLM will interpret this and select files.
                                    </p>
                                </div>
                            </div>
                        )}
                    </div>

                    <div className="space-y-2">
                        <Label>Analysis Prompt</Label>
                        <Textarea 
                            value={module.analysis_prompt} 
                            onChange={(e) => onUpdate({...module, analysis_prompt: e.target.value})}
                            className="font-mono text-xs min-h-[150px]" 
                        />
                        <p className="text-[10px] text-muted-foreground">
                            Use <code>{"{{data}}"}</code> to inject data.
                        </p>
                    </div>

                    <div className="space-y-2">
                        <Label>Dependencies</Label>
                        <div className="flex flex-wrap gap-2 border p-2 rounded-md min-h-[40px]">
                            {availableModules.length === 0 ? (
                                <span className="text-xs text-muted-foreground">No other modules available</span>
                            ) : availableModules.map(mid => (
                                <Badge 
                                    key={mid}
                                    variant={module.dependencies.includes(mid) ? "default" : "outline"}
                                    className="cursor-pointer hover:opacity-80"
                                    onClick={() => toggleDependency(mid)}
                                >
                                    {allModules[mid]?.name || mid}
                                </Badge>
                            ))}
                        </div>
                        <p className="text-[10px] text-muted-foreground">
                            Select modules that must complete before this one starts.
                    </p>
                </div>
            </CardContent>
            )}
        </Card>
    )
}