import React, { useEffect, useMemo, useRef, useState } from 'react';
import { ChevronDown, Tag, Eye, Plus, X, Loader2 } from 'lucide-react';
import { useStore } from '../store/useStore';
import type { TemplateClass } from '../store/useStore';
import { cn } from '../lib/utils';
import { getActiveTemplate } from '../lib/templateSelection';
import { analyzeMask, updateTemplate, type MaskAnalysisResult } from '../lib/api';

export function OntologyInspector() {
  const templates = useStore((state) => state.templates);
  const activeTemplateId = useStore((state) => state.activeTemplateId);
  const activeClassId = useStore((state) => state.activeClassId);
  const activeClass = useStore((state) => state.activeClass);
  const frames = useStore((state) => state.frames);
  const currentFrameIndex = useStore((state) => state.currentFrameIndex);
  const masks = useStore((state) => state.masks);
  const selectedMaskIds = useStore((state) => state.selectedMaskIds);
  const maskPreviewOpacity = useStore((state) => state.maskPreviewOpacity);
  const setMasks = useStore((state) => state.setMasks);
  const updateTemplateStore = useStore((state) => state.updateTemplate);
  const setActiveTemplateId = useStore((state) => state.setActiveTemplateId);
  const setActiveClass = useStore((state) => state.setActiveClass);
  const setMaskPreviewOpacity = useStore((state) => state.setMaskPreviewOpacity);

  const [showAddForm, setShowAddForm] = useState(false);
  const [newClassName, setNewClassName] = useState('');
  const [newClassColor, setNewClassColor] = useState('#06b6d4');
  const [isSavingClass, setIsSavingClass] = useState(false);
  const [classSaveMessage, setClassSaveMessage] = useState('');
  const [maskAnalysis, setMaskAnalysis] = useState<MaskAnalysisResult | null>(null);
  const [isAnalyzingMask, setIsAnalyzingMask] = useState(false);
  const [analysisMessage, setAnalysisMessage] = useState('');

  const activeTemplate = getActiveTemplate(templates, activeTemplateId);
  const templateClasses = activeTemplate?.classes || [];
  const allClasses = [...templateClasses].sort((a, b) => b.zIndex - a.zIndex);
  const selectedMask = masks.find((mask) => selectedMaskIds.includes(mask.id)) || null;
  const currentFrame = frames[currentFrameIndex] || null;
  const classButtonRefs = useRef(new Map<string, HTMLButtonElement>());

  const selectedMaskClass = useMemo(() => {
    if (!selectedMask) return null;
    const allTemplateClasses = templates.flatMap((template) => (
      template.classes.map((templateClass) => ({ template, templateClass }))
    ));
    const selectedName = selectedMask.className || selectedMask.label;
    return allTemplateClasses.find(({ templateClass }) => selectedMask.classId && templateClass.id === selectedMask.classId)
      || allTemplateClasses.find(({ templateClass }) => templateClass.name === selectedName && templateClass.color === selectedMask.color)
      || allTemplateClasses.find(({ templateClass }) => templateClass.name === selectedName)
      || null;
  }, [selectedMask?.classId, selectedMask?.className, selectedMask?.color, selectedMask?.id, selectedMask?.label, templates]);

  useEffect(() => {
    if (!selectedMaskClass) return;
    if (activeTemplateId !== selectedMaskClass.template.id) {
      setActiveTemplateId(selectedMaskClass.template.id);
    }
    setActiveClass(selectedMaskClass.templateClass);
    const timer = window.setTimeout(() => {
      const node = classButtonRefs.current.get(selectedMaskClass.templateClass.id);
      node?.scrollIntoView?.({ block: 'nearest' });
      node?.focus?.({ preventScroll: true });
    }, 0);
    return () => window.clearTimeout(timer);
  }, [activeTemplateId, selectedMaskClass, setActiveClass, setActiveTemplateId]);

  const handleSelectClass = (templateClass: TemplateClass) => {
    if (activeTemplate && !activeTemplateId) {
      setActiveTemplateId(activeTemplate.id);
    }
    setActiveClass(templateClass);
    const selectedIdSet = new Set(selectedMaskIds);
    const hasSelectedMasks = masks.some((mask) => selectedIdSet.has(mask.id));
    if (!hasSelectedMasks) return;

    const templateId = activeTemplate?.id || activeTemplateId || undefined;
    const updatedMasks = masks.map((mask) => {
      if (!selectedIdSet.has(mask.id)) return mask;
      return {
        ...mask,
        templateId: templateId || mask.templateId,
        classId: templateClass.id,
        className: templateClass.name,
        classZIndex: templateClass.zIndex,
        label: templateClass.name,
        color: templateClass.color,
        saveStatus: mask.annotationId ? 'dirty' as const : 'draft' as const,
        saved: mask.annotationId ? false : mask.saved,
      };
    });
    const selectedMasksOnTop = selectedMaskIds
      .map((id) => updatedMasks.find((mask) => mask.id === id))
      .filter((mask): mask is (typeof updatedMasks)[number] => Boolean(mask));
    setMasks([
      ...updatedMasks.filter((mask) => !selectedIdSet.has(mask.id)),
      ...selectedMasksOnTop,
    ]);
  };

  const refreshMaskAnalysis = async (extractSkeleton = false) => {
    if (!selectedMask || !currentFrame) {
      setMaskAnalysis(null);
      setAnalysisMessage(selectedMask ? '当前帧信息不可用，无法读取后端属性' : '请选择一个 mask 查看后端属性');
      return;
    }
    setIsAnalyzingMask(true);
    setAnalysisMessage('');
    try {
      const result = await analyzeMask(selectedMask, currentFrame, { extractSkeleton });
      setMaskAnalysis(result);
      setAnalysisMessage(result.message);
    } catch (err) {
      console.error('Mask analysis failed:', err);
      setMaskAnalysis(null);
      setAnalysisMessage('后端属性读取失败');
    } finally {
      setIsAnalyzingMask(false);
    }
  };

  React.useEffect(() => {
    void refreshMaskAnalysis(false);
    // selectedMask is intentionally tracked by id and geometry fields to avoid
    // re-running analysis for unrelated store changes.
  }, [selectedMask?.id, selectedMask?.segmentation, selectedMask?.points, currentFrame?.id]);

  const handleAddCustom = async () => {
    if (!newClassName.trim()) return;
    if (!activeTemplate) {
      setClassSaveMessage('请先选择一个模板');
      return;
    }
    const maxZ = templateClasses.length > 0 ? Math.max(...templateClasses.map((c) => c.zIndex)) : 0;
    const newClass: TemplateClass = {
      id: `custom-${Date.now()}`,
      name: newClassName.trim(),
      color: newClassColor,
      zIndex: maxZ + 10,
      category: '自定义',
    };
    setIsSavingClass(true);
    setClassSaveMessage('');
    try {
      const updated = await updateTemplate(activeTemplate.id, {
        name: activeTemplate.name,
        description: activeTemplate.description,
        classes: [...templateClasses, newClass],
        rules: activeTemplate.rules || [],
      });
      updateTemplateStore(updated);
      setActiveTemplateId(updated.id);
      handleSelectClass(newClass);
      setNewClassName('');
      setShowAddForm(false);
      setClassSaveMessage('自定义分类已保存到后端模板');
    } catch (err) {
      console.error('Save custom class failed:', err);
      setClassSaveMessage('自定义分类保存失败');
    } finally {
      setIsSavingClass(false);
    }
  };

  return (
    <div className="w-60 bg-[#0d0d0d] flex flex-col border-l border-white/5 shrink-0 z-10 overflow-hidden">
      <div className="flex-1 overflow-y-auto seg-scrollbar p-4 flex flex-col gap-6">
        {/* Template Selector */}
        <div>
          <h3 className="text-[10px] font-bold text-gray-500 uppercase tracking-widest mb-2">当前激活模板</h3>
          <div className="relative">
            <select
              value={activeTemplate?.id || ''}
              onChange={(e) => {
                setActiveTemplateId(e.target.value || null);
                setActiveClass(null);
              }}
              className="w-full bg-[#1a1a1a] border border-white/10 rounded-lg px-3 py-2 text-xs text-gray-300 appearance-none cursor-pointer focus:outline-none focus:border-cyan-500/50"
            >
              <option value="">-- 选择模板 --</option>
              {templates.map((t) => (
                <option key={t.id} value={t.id}>{t.name}</option>
              ))}
            </select>
            <ChevronDown size={12} className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 pointer-events-none" />
          </div>
          {activeTemplate && (
            <div className="mt-2 text-[10px] text-gray-600">
              {activeTemplate.classes?.length ?? 0} 个分类来自模板
            </div>
          )}
        </div>

        {/* Workspace Mask Opacity */}
        <div>
          <div className="mb-2 flex items-center justify-between">
            <label htmlFor="workspace-mask-opacity" className="text-[10px] font-bold text-gray-500 uppercase tracking-widest">
              遮罩透明度
            </label>
            <span className="text-[10px] font-mono text-cyan-400">{maskPreviewOpacity}%</span>
          </div>
          <input
            id="workspace-mask-opacity"
            aria-label="遮罩透明度"
            type="range"
            min={10}
            max={100}
            step={5}
            value={maskPreviewOpacity}
            onChange={(event) => setMaskPreviewOpacity(Number(event.target.value))}
            className="w-full accent-cyan-500"
          />
        </div>

        {/* Semantic Classification Tree */}
        <div>
           <h3 className="text-[10px] font-bold text-gray-500 uppercase tracking-widest mb-3 flex justify-between items-center">
             <span>语义分类树 (高度/Z-Index)</span>
           </h3>
           <div className="space-y-2">
             {allClasses.map(cls => (
               <div key={cls.id} className="flex flex-col gap-1">
                 <button
                   type="button"
                   ref={(node) => {
                     if (node) {
                       classButtonRefs.current.set(cls.id, node);
                     } else {
                       classButtonRefs.current.delete(cls.id);
                     }
                   }}
                   onClick={() => handleSelectClass(cls)}
                   aria-current={activeClassId === cls.id ? 'true' : undefined}
                   className={cn(
                     'flex items-center justify-between p-2 rounded bg-white/5 hover:bg-white/10 cursor-pointer group transition-colors text-left border',
                     activeClassId === cls.id ? 'border-cyan-500/50 bg-cyan-500/10' : 'border-transparent',
                   )}
                 >
                   <div className="flex items-center gap-2">
                     <span className="w-2.5 h-2.5 rounded-sm" style={{ backgroundColor: cls.color }} />
                     <span className="text-xs font-medium text-gray-200">{cls.name}</span>
                   </div>
                   <div className="flex items-center gap-3">
                     <span className="text-[10px] text-gray-500 font-mono">z:{cls.zIndex}</span>
                     <Eye size={14} className="text-gray-500 group-hover:text-gray-300" />
                   </div>
                 </button>
               </div>
             ))}
             {allClasses.length === 0 && (
               <div className="text-xs text-gray-600 text-center py-4">请先选择一个模板</div>
             )}
           </div>
        </div>

        {/* Add Custom Class */}
        <div>
           <div className="flex justify-between items-center mb-2">
             <h3 className="text-[10px] font-bold text-gray-500 uppercase tracking-widest">自定义分类</h3>
             <button
               onClick={() => setShowAddForm(!showAddForm)}
               className="text-cyan-400 hover:text-cyan-300 transition-colors"
             >
               <Plus size={12} />
             </button>
           </div>
           {showAddForm && (
             <div className="bg-[#1a1a1a] border border-white/10 rounded-lg p-3 space-y-2">
               <div className="flex items-center gap-2">
                 <input
                   type="color"
                   value={newClassColor}
                   onChange={(e) => setNewClassColor(e.target.value)}
                   className="w-8 h-8 rounded bg-transparent border-0 cursor-pointer"
                 />
                 <input
                   type="text"
                   value={newClassName}
                   onChange={(e) => setNewClassName(e.target.value)}
                   placeholder="分类名称"
                   className="flex-1 bg-[#111] border border-white/10 rounded px-2 py-1 text-xs text-white"
                   onKeyDown={(e) => e.key === 'Enter' && handleAddCustom()}
                 />
                 <button onClick={handleAddCustom} className="text-cyan-400 hover:text-cyan-300">
                   {isSavingClass ? <Loader2 size={14} className="animate-spin" /> : <Plus size={14} />}
                 </button>
                 <button onClick={() => setShowAddForm(false)} className="text-gray-500 hover:text-gray-300">
                   <X size={14} />
                 </button>
               </div>
             </div>
           )}
           {classSaveMessage && (
             <div className="mt-2 text-[10px] text-gray-500">{classSaveMessage}</div>
           )}
        </div>

        {/* Current Active Object Properties */}
        <div className="mt-4 pt-4 border-t border-[#222]">
           <h3 className="text-[10px] font-bold text-gray-500 uppercase tracking-widest mb-3">特定目标实例属性追踪</h3>
           <div className="bg-white/5 rounded-lg p-3">
             <div className="flex items-center gap-2 mb-3">
               <Tag size={12} className="text-cyan-400" />
               <span className="text-xs font-semibold text-gray-200">
                 {activeClass?.name || activeTemplate?.name || '未选择'}
               </span>
             </div>
             <div className="space-y-3">
               <div className="flex items-center justify-between">
                 <span className="text-[10px] text-gray-500 uppercase">当前选中区域:</span>
                 <span className="text-xs font-mono text-gray-300">{selectedMaskIds.length}</span>
               </div>
               <div className="space-y-1">
                 <label className="text-[10px] text-gray-500 uppercase">后端模型置信度</label>
                 <div className="h-1.5 w-full bg-white/10 rounded-full overflow-hidden">
                    <div
                      className="h-full bg-green-500"
                      style={{ width: `${Math.round((maskAnalysis?.confidence ?? 0) * 100)}%` }}
                    />
                 </div>
                 <div className="text-[10px] font-mono text-green-500 text-right">
                   {maskAnalysis?.confidence != null ? maskAnalysis.confidence.toFixed(4) : '无模型分数'}
                 </div>
               </div>
               <div className="flex items-center justify-between">
                 <span className="text-[10px] text-gray-500 uppercase">后端拓扑锚点:</span>
                 <span className="text-xs font-mono text-gray-300">{maskAnalysis?.topology_anchor_count ?? 0} 节点</span>
               </div>
               {analysisMessage && (
                 <div className="text-[10px] leading-relaxed text-gray-500">{analysisMessage}</div>
               )}
               <button
                 onClick={() => refreshMaskAnalysis(true)}
                 disabled={!selectedMask || isAnalyzingMask}
                 className="w-full mt-2 bg-white/5 hover:bg-white/10 border border-white/10 text-xs text-gray-300 py-1.5 rounded transition-colors disabled:opacity-40 disabled:cursor-not-allowed"
               >
                 {isAnalyzingMask ? '提取中...' : '重新提取拓扑锚点'}
               </button>
             </div>
           </div>
        </div>
      </div>
    </div>
  );
}
