import React, { useEffect, useState, useRef } from 'react';
import { flushSync } from 'react-dom';
import { useNavigate, useSearchParams } from 'react-router-dom';
import Sidebar from '../components/Sidebar';
import { 
  Check, Printer, Undo, Redo, Bold, Italic, Underline, 
  AlignLeft, AlignCenter, AlignRight, Table, Image as ImageIcon,
  Video, Play, Pause, Plus, X, ChevronLeft, Download, Bot, Sparkles, Send, Loader2,
  Mic, MicOff, ImagePlus
} from 'lucide-react';
import { User, Report, Template, CapturedFrame, SystemSettings, FormField, DEFAULT_FORM_FIELDS } from '../types';
import { defaultReportContent } from '../utils/defaultContent';
import { printDocument } from '../utils/print';
import { storage } from '../utils/storage';

export default function ReportEditor() {
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const reportId = searchParams.get('id');
  const restoreFlag = searchParams.get('restore');
  
  const [currentUser, setCurrentUser] = useState<User | null>(null);
  const [reportData, setReportData] = useState<Partial<Report>>({
    title: '腹腔镜胆囊切除术报告',
    patientName: '',
    hospitalId: '',
    patientGender: '',
    patientAge: '',
    department: '',
    bedNumber: '',
    surgeryDate: '',
    startHour: '',
    startMinute: '',
    endHour: '',
    endMinute: '',
    surgeon: [],
    assistant: [],
    anesthesiologist: [],
    anesthesiaType: '',
    reportNote: '',
    status: 'draft'
  });

  const [templates, setTemplates] = useState<Template[]>([]);
  const [videos, setVideos] = useState<{id: string, name: string, url: string, duration: number}[]>([]);
  const [currentVideoIndex, setCurrentVideoIndex] = useState(-1);
  const [capturedFrames, setCapturedFrames] = useState<CapturedFrame[]>([]);
  const [isPlaying, setIsPlaying] = useState(false);
  const [currentTime, setCurrentTime] = useState(0);
  const [duration, setDuration] = useState(0);
  const [isSaved, setIsSaved] = useState(false);
  const [exportModalOpen, setExportModalOpen] = useState(false);
  const [loadedTemplateId, setLoadedTemplateId] = useState('');
  const [pendingTemplateId, setPendingTemplateId] = useState<string | null>(null);
  const prevVideoCountRef = useRef(0);
  
  const [activeTab, setActiveTab] = useState<'info' | 'video' | 'ai'>('info');
  const [activeFieldKey, setActiveFieldKey] = useState<string | null>(null);

  // AI 撰写相关状态
  const [chatInput, setChatInput] = useState<string>('');
  const [chatMessages, setChatMessages] = useState<{id: string, role: 'user'|'model', content: string}[]>([]);
  const [isGenerating, setIsGenerating] = useState(false);
  const [aiSelectedFrames, setAiSelectedFrames] = useState<number[]>([]);
  const [aiTargetRegion, setAiTargetRegion] = useState<string>('surgical-steps');
  const [aiModifyEnabled, setAiModifyEnabled] = useState(true);
  const [isListening, setIsListening] = useState(false);
  const [aiUploadedImages, setAiUploadedImages] = useState<{id: number, dataUrl: string}[]>([]);
  const speechRecognitionRef = useRef<any>(null);

  useEffect(() => {
    if (!editorRef.current) return;
    const allFields = editorRef.current.querySelectorAll('.field-value');
    allFields.forEach(el => {
      (el as HTMLElement).style.backgroundColor = '';
      (el as HTMLElement).style.outline = '';
      (el as HTMLElement).style.outlineOffset = '';
    });
    if (activeFieldKey) {
      const targetEl = editorRef.current.querySelector(`.field-value[data-bind="\${activeFieldKey}"]`) as HTMLElement;
      if (targetEl) {
        targetEl.style.backgroundColor = '#f1f5f9';
        targetEl.style.outline = '1px solid #94a3b8';
        targetEl.style.outlineOffset = '1px';
        targetEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
      }
    }
  }, [activeFieldKey]);

  const [formFields, setFormFields] = useState<FormField[]>([]);
  const [openDropdown, setOpenDropdown] = useState<string | null>(null);
  const [touched, setTouched] = useState<Record<string, boolean>>({});

  const editorRef = useRef<HTMLDivElement>(null);
  const videoRef = useRef<HTMLVideoElement>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const videoInputRef = useRef<HTMLInputElement>(null);
  const contentLoadedRef = useRef(false);
  const contentRef = useRef('');
  const stateRef = useRef({ reportData, videos, capturedFrames, activeTab, loadedTemplateId });

  const draftKey = currentUser ? `reportEditorDraft_\${currentUser.username}` : '';

  const updatePageHeight = () => {
    if (!editorRef.current) return;
    const contentHeight = editorRef.current.scrollHeight;
    const pageHeightMm = 297;
    const mmToPx = 3.7795275591;
    const pages = Math.max(2, Math.ceil(contentHeight / (pageHeightMm * mmToPx)));
    editorRef.current.style.minHeight = `\${pages * pageHeightMm}mm`;
  };

  const saveDraftToStorage = React.useCallback(() => {
    const user = storage.get<User | null>('currentUser', null);
    const key = user ? `reportEditorDraft_\${user.username}` : '';
    if (key) {
      const currentContent = contentRef.current || editorRef.current?.innerHTML || '';
      storage.set(key, {
        content: currentContent,
        draftReportId: reportId || null,
        reportData: stateRef.current.reportData,
        videos: stateRef.current.videos,
        capturedFrames: stateRef.current.capturedFrames,
        activeTab: stateRef.current.activeTab,
        loadedTemplateId: stateRef.current.loadedTemplateId
      });
    }
  }, [reportId]);

  useEffect(() => {
    const user = storage.get<User | null>('currentUser', null);
    if (!user) { navigate('/'); return; }
    setCurrentUser(user);

    const savedFields = storage.get<FormField[]>('formFieldsConfig', []);
    if (savedFields.length > 0) {
      setFormFields(savedFields);
    } else {
      setFormFields(DEFAULT_FORM_FIELDS);
      storage.set('formFieldsConfig', DEFAULT_FORM_FIELDS);
    }

    const allTemplates = storage.get<Template[]>('templates', []);
    setTemplates(allTemplates);

    if (reportId) {
      const reports = storage.get<Report[]>('reports', []);
      const found = reports.find(r => r.id === reportId);
      if (found) {
        setReportData(found);
        if (found.capturedFrames) setCapturedFrames(found.capturedFrames);
        if (found.videos) setVideos(found.videos);
        if (editorRef.current) {
          editorRef.current.innerHTML = found.content;
          contentRef.current = found.content;
          contentLoadedRef.current = true;
          setTimeout(() => updatePageHeight(), 0);
        }
      }
    } else if (!contentLoadedRef.current && editorRef.current) {
      editorRef.current.innerHTML = defaultReportContent;
      contentRef.current = defaultReportContent;
      contentLoadedRef.current = true;
      setTimeout(() => updatePageHeight(), 0);
    }
  }, [reportId, navigate]);

  const execCmd = (command: string, value: string | undefined = undefined) => {
    editorRef.current?.focus();
    document.execCommand(command, false, value);
    editorRef.current?.focus();
    if (editorRef.current) contentRef.current = editorRef.current.innerHTML;
    saveDraftToStorage();
  };

  const handleVideoUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(e.target.files || []) as File[];
    const newVideos = files.map(file => ({
      id: Math.random().toString(36).substr(2, 9),
      name: file.name,
      url: URL.createObjectURL(file),
      duration: 0
    }));
    setVideos([...videos, ...newVideos]);
    if (currentVideoIndex === -1 && newVideos.length > 0) setCurrentVideoIndex(0);
  };

  const togglePlay = () => {
    if (!videoRef.current) return;
    if (isPlaying) videoRef.current.pause();
    else videoRef.current.play();
    setIsPlaying(!isPlaying);
  };

  const formatTime = (seconds: number) => {
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `\${mins.toString().padStart(2, '0')}:\${secs.toString().padStart(2, '0')}`;
  };

  const captureFrame = () => {
    if (!videoRef.current || !canvasRef.current || currentVideoIndex === -1) return;
    const video = videoRef.current;
    const canvas = canvasRef.current;
    
    // Create an unconstrained canvas to get native resolution or properly scaled frame
    const scale = Math.min(1, 800 / video.videoWidth);
    canvas.width = video.videoWidth * scale;
    canvas.height = video.videoHeight * scale;
    const ctx = canvas.getContext('2d');
    ctx?.drawImage(video, 0, 0, canvas.width, canvas.height);

    const newFrame: CapturedFrame = {
      id: Date.now(),
      videoIndex: currentVideoIndex,
      videoName: videos[currentVideoIndex].name,
      time: video.currentTime,
      timeFormatted: formatTime(video.currentTime),
      dataUrl: canvas.toDataURL('image/jpeg', 0.8),
      isManual: true
    };
    
    setCapturedFrames([...capturedFrames, newFrame]);
  };

  const saveReport = (status: 'draft' | 'completed') => {
    const content = editorRef.current?.innerHTML || '';
    const now = new Date().toISOString();
    const finalReport: Report = {
      ...(reportData as Report),
      id: reportId || 'RPT_' + Date.now(),
      content,
      author: currentUser?.username || '',
      authorName: currentUser?.name || '',
      createdAt: reportData.createdAt || now.split('T')[0],
      status,
      capturedFrames,
      videos,
      updatedAt: now
    };

    const reports = storage.get<Report[]>('reports', []);
    let updatedReports;
    if (reportId) {
      updatedReports = reports.map(r => r.id === reportId ? finalReport : r);
    } else {
      updatedReports = [...reports, finalReport];
    }

    storage.set('reports', updatedReports);
    setIsSaved(true);
    setTimeout(() => setIsSaved(false), 3000);
    if (status === 'completed') navigate('/report-manage');
  };

  const handleAiLocalImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (!files) return;
    Array.from(files).forEach((file: File) => {
      const reader = new FileReader();
      reader.onload = (ev) => {
        if (ev.target?.result) {
          setAiUploadedImages(prev => [...prev, { id: Date.now() + Math.random(), dataUrl: ev.target!.result as string }]);
        }
      };
      reader.readAsDataURL(file);
    });
    // reset input
    e.target.value = '';
  };

  const toggleListening = () => {
    if (isListening) {
      setIsListening(false);
      if (speechRecognitionRef.current) {
        speechRecognitionRef.current.stop();
      }
    } else {
      const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;
      if (!SpeechRecognition) {
        alert("您的浏览器不支持语音识别功能，请使用 Chrome 等支持该特性的浏览器。");
        return;
      }
      const recognition = new SpeechRecognition();
      recognition.lang = 'zh-CN';
      recognition.continuous = false;
      recognition.interimResults = false;

      recognition.onstart = () => setIsListening(true);
      recognition.onresult = (event: any) => {
        const transcript = event.results[0][0].transcript;
        setChatInput(prev => prev + (prev ? ' ' : '') + transcript);
      };
      recognition.onerror = (event: any) => {
        console.error("Speech recognition error", event.error);
        setIsListening(false);
      };
      recognition.onend = () => {
        setIsListening(false);
      };
      
      speechRecognitionRef.current = recognition;
      recognition.start();
    }
  };

  const handleAIGenerate = async (text: string) => {
    if (!text.trim()) return;

    const userMsgId = Date.now().toString();
    const newUserMsg = { id: userMsgId, role: 'user' as const, content: text };
    setChatMessages(prev => [...prev, newUserMsg]);
    setChatInput('');
    setIsGenerating(true);

    try {
      const { GoogleGenAI, Type } = await import('@google/genai');
      const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
      const sysSettings = storage.get<SystemSettings>('systemSettings', {} as SystemSettings);
      const modelName = sysSettings.geminiModel || 'gemini-3-flash-preview';

      const historyContents = chatMessages.map(msg => ({
        role: msg.role === 'user' ? 'user' : 'model',
        parts: [{ text: msg.content }]
      }));

      const currentParts: any[] = [];
      const selectedFrameDataUrls = aiSelectedFrames
        .map(id => capturedFrames.find(f => f.id === id)?.dataUrl)
        .filter(Boolean) as string[];
      
      const allImages = [...selectedFrameDataUrls, ...aiUploadedImages.map(i => i.dataUrl)];
      
      allImages.forEach(url => {
        const match = url.match(/^data:(image\/[a-z]+);base64,(.+)$/);
        if (match) {
          currentParts.push({ inlineData: { mimeType: match[1], data: match[2] } });
        }
      });
      // 清空本地上传的图片以备下次
      setAiUploadedImages([]);

      const targetRegion = editorRef.current?.querySelector(`.ai-region[data-ai-id="${aiTargetRegion}"]`);
      const currentHtml = targetRegion ? targetRegion.innerHTML : '';

      if (aiModifyEnabled) {
        currentParts.push({
          text: `【当前待修改内容的 HTML 源码】:\n${currentHtml}\n\n【医生的期望/修改要求】: ${text}`
        });
      } else {
        currentParts.push({
          text: `【医生的指令/要求】: ${text}`
        });
      }

      historyContents.push({ role: 'user', parts: currentParts });

      const systemInstruction = aiModifyEnabled
        ? "你是一名专业的外科医生助理。根据用户提供的（图像）和（修改要求），修改（当前待修改内容的 HTML 源码）。\n" +
          "你需要返回 JSON 数据，其中包含两部分：\n" +
          "1. 'reply': 向医生报告您做了哪些修改（友好的文本对话回复，如‘好的，我已为您更新了相关描述。’）。\n" +
          "2. 'updatedHtml': 修改后的完整 HTML 代码片段（保留原有的 HTML 格式，如 `<p>` 标签和行内样式）。\n" +
          "你的输出必须严格符合 JSON 结构，不要包含 markdown 代码块的包裹。"
        : "你是一名专业的外科医生助理。根据用户提供的（图像）和（指令），回答问题、提取信息或生成段落总结。\n" +
          "你只需要返回 JSON 数据中的 'reply' 字段即可（友好的文本对话回复）。不要返回 updatedHtml。\n" +
          "你的输出必须严格符合 JSON 结构，不要包含 markdown 代码块的包裹。";

      const responseSchema = aiModifyEnabled
        ? {
            type: Type.OBJECT,
            properties: {
                reply: { type: Type.STRING },
                updatedHtml: { type: Type.STRING }
            },
            required: ["reply", "updatedHtml"]
          }
        : {
            type: Type.OBJECT,
            properties: {
                reply: { type: Type.STRING }
            },
            required: ["reply"]
          };

      const response = await ai.models.generateContent({
        model: modelName,
        contents: historyContents as any,
        config: {
          systemInstruction,
          responseMimeType: "application/json",
          responseSchema,
        }
      });

      const responseJson = JSON.parse(response.text || '{}');
      if (responseJson.reply) {
        setChatMessages(prev => [...prev, { id: Date.now().toString(), role: 'model', content: responseJson.reply }]);
      }
      if (responseJson.updatedHtml) {
        injectAIText(responseJson.updatedHtml);
      }

    } catch (error: any) {
      console.error(error);
      setChatMessages(prev => [...prev, { id: Date.now().toString(), role: 'model', content: `[系统错误]: ${error.message}` }]);
    } finally {
      setIsGenerating(false);
    }
  };

  const injectAIText = (htmlContent: string) => {
    if (!editorRef.current) return;
    const targetRegion = editorRef.current.querySelector(`.ai-region[data-ai-id="${aiTargetRegion}"]`);
    if (targetRegion) {
      const regionTitle = availableAiRegions.find(r => r.id === aiTargetRegion)?.title || '';
      const badgeLabel = regionTitle ? `${regionTitle}-AI可编辑区域` : 'AI可编辑区域';
      targetRegion.innerHTML = `
        <div contenteditable="false" style="position: absolute; top: -10px; right: 12px; background: #3b82f6; color: white; font-size: 10px; padding: 2px 8px; border-radius: 12px; cursor: default; white-space: nowrap; z-index: 10; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">${badgeLabel}</div>
        ${htmlContent}
      `;
      contentRef.current = editorRef.current.innerHTML;
      saveDraftToStorage();
      const targetElement = targetRegion as HTMLElement;
      targetElement.style.transition = 'background-color 0.5s';
      targetElement.style.backgroundColor = '#dbeafe';
      setTimeout(() => {
        targetElement.style.backgroundColor = '#eff6ff';
      }, 500);
    } else {
      execCmd('insertHTML', htmlContent);
    }
  };

  const checkAiRegions = () => {
    if (!editorRef.current) return [];
    const regions = Array.from(editorRef.current.querySelectorAll('.ai-region'));
    return regions.map((el: any) => {
      const id = el.getAttribute('data-ai-id') || '';
      const title = el.getAttribute('data-ai-title') || id;
      return { id, title };
    });
  };

  const availableAiRegions = checkAiRegions();

  return (
    <div className="flex bg-slate-50 h-screen overflow-hidden">
      <Sidebar />
      
      <div className="flex-1 flex flex-col h-full overflow-hidden">
        {/* Header */}
        <header className="h-16 bg-white border-b border-slate-200 flex items-center justify-between px-6 shrink-0 z-10">
          <div className="flex items-center gap-4">
            <button 
              onClick={() => navigate('/report-manage')}
              className="p-2 rounded-lg hover:bg-slate-100 text-slate-500 transition-colors"
            >
              <ChevronLeft size={20} />
            </button>
            <h1 className="text-lg font-bold text-slate-800">
              {reportId ? `编辑报告: \${reportId}` : '新建手术报告'}
            </h1>
          </div>
          <div className="flex items-center gap-3">
            {isSaved && (
              <span className="text-xs text-green-600 font-bold flex items-center gap-1">
                <Check size={14} /> 已保存
              </span>
            )}
            <button 
              onClick={() => saveReport('draft')}
              className="px-4 py-2 bg-slate-100 text-slate-600 rounded text-sm font-medium hover:bg-slate-200"
            >
              保存草稿
            </button>
            <button 
              onClick={() => saveReport('completed')}
              className="px-4 py-2 bg-blue-600 text-white flex items-center gap-2 rounded text-sm font-medium hover:bg-blue-700"
            >
              <Check size={16} />
              完成报告
            </button>
            <button 
              onClick={() => editorRef.current && printDocument(editorRef.current.innerHTML)}
              className="p-2 rounded bg-slate-100 text-slate-600 hover:bg-slate-200"
            >
              <Printer size={18} />
            </button>
          </div>
        </header>

        <div className="flex-1 flex overflow-hidden">
          {/* Main Editor Section */}
          <div className="flex-1 flex flex-col bg-slate-200 border-r border-slate-200 overflow-hidden relative">
            <div className="flex items-center gap-1 p-2 bg-white border-b border-slate-200 shrink-0">
               {/* 简化版工具栏 */}
               <button onClick={() => execCmd('undo')} className="p-1.5 hover:bg-slate-100 rounded text-slate-600"><Undo size={16}/></button>
               <button onClick={() => execCmd('redo')} className="p-1.5 hover:bg-slate-100 rounded text-slate-600"><Redo size={16}/></button>
               <div className="w-px h-6 bg-slate-300 mx-1"></div>
               <button onClick={() => execCmd('bold')} className="p-1.5 hover:bg-slate-100 rounded text-slate-600"><Bold size={16}/></button>
               <button onClick={() => execCmd('italic')} className="p-1.5 hover:bg-slate-100 rounded text-slate-600"><Italic size={16}/></button>
               <button onClick={() => execCmd('underline')} className="p-1.5 hover:bg-slate-100 rounded text-slate-600"><Underline size={16}/></button>
               <div className="w-px h-6 bg-slate-300 mx-1"></div>
               <button onClick={(e) => { e.preventDefault(); execCmd('justifyLeft'); }} className="p-1.5 hover:bg-slate-100 rounded text-slate-600"><AlignLeft size={16}/></button>
               <button onClick={(e) => { e.preventDefault(); execCmd('justifyCenter'); }} className="p-1.5 hover:bg-slate-100 rounded text-slate-600"><AlignCenter size={16}/></button>
               <button onClick={(e) => { e.preventDefault(); execCmd('justifyRight'); }} className="p-1.5 hover:bg-slate-100 rounded text-slate-600"><AlignRight size={16}/></button>
            </div>
            
            <div className="flex-1 overflow-y-auto w-full flex justify-center py-8">
              <div 
                ref={editorRef}
                contentEditable
                className="bg-white shadow-md p-10 w-[800px] min-h-[1100px] outline-none"
                style={{ fontFamily: 'SimSun', lineHeight: '1.5', transition: 'width 0.2s', paddingBottom: '100px' }}
                onInput={(e) => { contentRef.current = editorRef.current?.innerHTML || ''; }}
              >
              </div>
            </div>
          </div>

          {/* Right Sidebar */}
          <aside className="w-[360px] bg-white flex flex-col shrink-0">
            <div className="flex border-b border-slate-200 shrink-0">
              <button 
                onClick={() => setActiveTab('info')}
                className={`flex-1 py-3 text-sm font-medium border-b-2 \${activeTab === 'info' ? 'border-blue-600 text-blue-600' : 'border-transparent text-slate-500 hover:text-slate-800'}`}
              >信息录入</button>
              <button 
                onClick={() => setActiveTab('video')}
                className={`flex-1 py-3 text-sm font-medium border-b-2 \${activeTab === 'video' ? 'border-blue-600 text-blue-600' : 'border-transparent text-slate-500 hover:text-slate-800'}`}
              >视频分析</button>
              <button 
                onClick={() => setActiveTab('ai')}
                className={`flex-1 py-3 text-sm font-medium border-b-2 flex items-center justify-center gap-1 \${activeTab === 'ai' ? 'border-blue-600 text-blue-600' : 'border-transparent text-slate-500 hover:text-slate-800'}`}
              >
                <Bot size={16} /> AI撰写
              </button>
            </div>

            <div className="flex-1 overflow-y-auto p-4 custom-scrollbar">
              {activeTab === 'info' && (
                <div className="space-y-4">
                  <div className="bg-blue-50 p-3 rounded-lg border border-blue-100 text-sm text-blue-800">
                    您可以在这里编辑右侧表单。这些值会自动同步到中间的报告占位符中。
                  </div>
                  {/* Basic bindings for the most common fields */}
                  <div className="space-y-1">
                    <label className="text-xs font-semibold text-slate-600">患者姓名</label>
                    <input type="text" className="w-full px-3 py-2 border rounded" value={(reportData as any).patientName || ''} onChange={(e) => {
                        const val = e.target.value; setReportData({...reportData, patientName: val});
                        // Sync to span
                        const s = editorRef.current?.querySelector('[data-bind="patientName"]') as HTMLElement;
                        if(s) s.innerText = val;
                    }} />
                  </div>
                  <div className="space-y-1">
                    <label className="text-xs font-semibold text-slate-600">住院号</label>
                    <input type="text" className="w-full px-3 py-2 border rounded" value={(reportData as any).hospitalId || ''} onChange={(e) => {
                        const val = e.target.value; setReportData({...reportData, hospitalId: val});
                        const s = editorRef.current?.querySelector('[data-bind="hospitalId"]') as HTMLElement;
                        if(s) s.innerText = val;
                    }} />
                  </div>
                  <div className="space-y-1">
                    <label className="text-xs font-semibold text-slate-600">手术名称</label>
                    <input type="text" className="w-full px-3 py-2 border rounded" value={(reportData as any).title || ''} onChange={(e) => {
                        const val = e.target.value; setReportData({...reportData, title: val});
                        const s = editorRef.current?.querySelector('[data-bind="title"]') as HTMLElement;
                        if(s) s.innerText = val;
                    }} />
                  </div>
                </div>
              )}

              {activeTab === 'video' && (
                <div className="space-y-4">
                  <input 
                    ref={videoInputRef}
                    type="file" 
                    accept="video/*" 
                    multiple 
                    className="hidden" 
                    onChange={handleVideoUpload} 
                  />
                  <button
                    onClick={() => videoInputRef.current?.click()}
                    className="w-full py-3 flex items-center justify-center gap-2 border-2 border-dashed border-slate-300 rounded-lg hover:border-blue-500 hover:text-blue-600 text-slate-500 transition-colors"
                  >
                    <Video size={18} />
                    <span className="text-sm font-medium">上传手术视频</span>
                  </button>

                  {videos.length > 0 && currentVideoIndex !== -1 && (
                    <div className="space-y-3">
                      <div className="relative bg-slate-900 rounded-lg overflow-hidden aspect-video">
                        <video 
                          ref={videoRef}
                          src={videos[currentVideoIndex].url}
                          className="w-full h-full"
                          onTimeUpdate={() => setCurrentTime(videoRef.current?.currentTime || 0)}
                          onLoadedMetadata={() => setDuration(videoRef.current?.duration || 0)}
                        />
                        {!isPlaying && (
                          <div className="absolute inset-0 flex items-center justify-center bg-black/40 cursor-pointer" onClick={togglePlay}>
                            <div className="w-12 h-12 rounded-full bg-white/20 flex items-center justify-center text-white">
                              <Play size={24} fill="currentColor" />
                            </div>
                          </div>
                        )}
                        <div className="absolute bottom-2 right-2 bg-black/60 text-white text-[10px] px-2 py-1 rounded">
                          {formatTime(currentTime)} / {formatTime(duration)}
                        </div>
                      </div>

                      <div className="flex gap-2">
                        <button onClick={togglePlay} className="px-3 py-2 bg-slate-100 rounded text-slate-700 hover:bg-slate-200">
                          {isPlaying ? <Pause size={16} /> : <Play size={16} />}
                        </button>
                        <button onClick={captureFrame} className="flex-1 bg-blue-600 text-white py-2 rounded text-sm font-medium hover:bg-blue-700">
                          截取当前画面并保存
                        </button>
                      </div>

                      <div className="grid grid-cols-2 gap-2 mt-4">
                        {capturedFrames.map((frame) => (
                          <div key={frame.id} className="relative group border border-slate-200 rounded p-1 bg-white">
                            <img src={frame.dataUrl} className="w-full aspect-video object-cover rounded" />
                            <div className="text-[10px] text-slate-500 mt-1 flex justify-between">
                              <span>{frame.timeFormatted}</span>
                              <span className="text-blue-600 cursor-pointer hover:underline" onClick={() => {
                                // Simple insert helper
                                execCmd('insertHTML', `<img src="\${frame.dataUrl}" style="max-width:200px" />`);
                              }}>插入插入文档</span>
                            </div>
                            <button 
                              onClick={() => setCapturedFrames(prev => prev.filter(f => f.id !== frame.id))}
                              className="absolute top-0 right-0 bg-red-500 text-white p-1 rounded-bl group-hover:opacity-100 opacity-0 transition-opacity"
                            >
                              <X size={12} />
                            </button>
                          </div>
                        ))}
                      </div>
                    </div>
                  )}
                </div>
              )}

              {activeTab === 'ai' && (
                <div className="flex flex-col h-full bg-slate-50 overflow-hidden">
                  {/* Chat History */}
                  <div className="flex-1 overflow-y-auto p-4 space-y-4">
                    {chatMessages.length === 0 ? (
                      <div className="text-center flex flex-col items-center justify-center h-full text-slate-400 space-y-3">
                        <Bot size={48} className="text-slate-300" />
                        <p className="text-xs">我是您的 AI 智能撰写助手，请在下方选择参考框架和图片后随时与我对话。</p>
                      </div>
                    ) : (
                      chatMessages.map(msg => (
                        <div key={msg.id} className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}>
                          <div className={`rounded-2xl px-4 py-2.5 max-w-[85%] text-sm ${msg.role === 'user' ? 'bg-blue-600 text-white rounded-tr-none' : 'bg-white border border-slate-200 text-slate-700 rounded-tl-none shadow-sm'}`}>
                            {msg.content}
                          </div>
                        </div>
                      ))
                    )}
                    {isGenerating && (
                      <div className="flex justify-start">
                        <div className="bg-white border border-slate-200 rounded-2xl rounded-tl-none px-4 py-2.5 shadow-sm flex gap-1 items-center">
                          <div className="w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce" />
                          <div className="w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce delay-75" />
                          <div className="w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce delay-150" />
                        </div>
                      </div>
                    )}
                  </div>

                  {/* Settings and Input Box */}
                  <div className="bg-white border-t border-slate-200 p-4 space-y-3 shrink-0">
                    <div className="flex flex-col gap-2">
                      <div className="flex items-center gap-4">
                        <div className="flex items-center gap-2 flex-1">
                          <label className="text-[11px] font-bold text-slate-500 shrink-0">指定修改区域</label>
                          <select 
                            value={aiTargetRegion}
                            onChange={(e) => setAiTargetRegion(e.target.value)}
                            disabled={!aiModifyEnabled}
                            className="flex-1 w-0 px-2 py-1.5 border border-slate-300 rounded text-xs bg-slate-50 focus:outline-none focus:ring-1 focus:ring-blue-500 disabled:opacity-50"
                          >
                            {availableAiRegions.length > 0 ? (
                              availableAiRegions.map(r => (
                                <option key={r.id} value={r.id}>{r.title}</option>
                              ))
                            ) : (
                              <option value="none">无区域 (将插入光标处)</option>
                            )}
                          </select>
                        </div>
                        <div className="flex items-center gap-1 shrink-0">
                          <input 
                            type="checkbox" 
                            id="aiModifyEnabled"
                            checked={aiModifyEnabled}
                            onChange={(e) => setAiModifyEnabled(e.target.checked)}
                            className="w-3.5 h-3.5 text-blue-600 rounded border-slate-300 focus:ring-blue-500 cursor-pointer"
                          />
                          <label htmlFor="aiModifyEnabled" className="text-[11px] text-slate-600 cursor-pointer select-none font-bold">
                            修改内容
                          </label>
                        </div>
                      </div>

                      {capturedFrames.length > 0 && (
                        <div className="flex flex-col gap-1.5">
                          <label className="text-[11px] font-bold text-slate-500 shrink-0">参考关键帧</label>
                          <div className="flex gap-2 overflow-x-auto pb-1 custom-scrollbar">
                            {capturedFrames.map(frame => {
                              const isSelected = aiSelectedFrames.includes(frame.id);
                              return (
                                <div 
                                  key={frame.id}
                                  onClick={() => {
                                    setAiSelectedFrames(prev => 
                                      isSelected ? prev.filter(id => id !== frame.id) : [...prev, frame.id]
                                    );
                                  }}
                                  className={`relative shrink-0 w-16 aspect-video rounded overflow-hidden border-2 cursor-pointer transition-all ${isSelected ? 'border-blue-600 scale-105' : 'border-transparent opacity-60 hover:opacity-100'}`}
                                >
                                  <img src={frame.dataUrl} className="w-full h-full object-cover" />
                                  {isSelected && (
                                    <div className="absolute top-0.5 right-0.5 bg-blue-600 rounded-full w-3 h-3 flex items-center justify-center">
                                      <Check size={8} className="text-white" />
                                    </div>
                                  )}
                                </div>
                              )
                            })}
                          </div>
                        </div>
                      )}
                    </div>

                    {/* Quick Prompts */}
                    <div className="flex flex-wrap gap-1.5 pb-1">
                      {['请详细描述手术步骤', '提取术中关键病灶信息', '生成简短的术后总结'].map(p => (
                        <button key={p} onClick={() => setChatInput(p)} className="px-2.5 py-1 bg-slate-100 hover:bg-slate-200 text-slate-600 text-[10px] rounded-full transition-colors whitespace-nowrap">
                          {p}
                        </button>
                      ))}
                    </div>

                    <div className="relative">
                      {/* 上传图片的预览区 */}
                      {aiUploadedImages.length > 0 && (
                        <div className="absolute top-2 left-2 flex gap-2 z-10 bg-white/80 p-1 rounded">
                          {aiUploadedImages.map(img => (
                            <div key={img.id} className="relative w-10 h-10 rounded overflow-hidden border border-slate-200 shadow-sm shrink-0">
                               <img src={img.dataUrl} className="w-full h-full object-cover" />
                               <button 
                                 onClick={() => setAiUploadedImages(prev => prev.filter(i => i.id !== img.id))} 
                                 className="absolute top-0 right-0 bg-red-500/80 hover:bg-red-500 text-white p-0.5 rounded-bl-md transition-colors"
                               >
                                 <X size={10}/>
                               </button>
                            </div>
                          ))}
                        </div>
                      )}

                      <textarea 
                        value={chatInput}
                        onChange={(e) => setChatInput(e.target.value)}
                        onKeyDown={(e) => {
                          if (e.key === 'Enter' && !e.shiftKey) {
                            e.preventDefault();
                            if (chatInput.trim() && !isGenerating) {
                              handleAIGenerate(chatInput);
                            }
                          }
                        }}
                        style={{ paddingTop: aiUploadedImages.length > 0 ? '56px' : '8px' }}
                        placeholder={isListening ? "正在聆听中..." : "输入修改意见... （按 Enter 发送）"}
                        className="w-full h-24 px-3 pr-[50px] border border-slate-300 rounded-lg text-sm bg-white focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none transition-all custom-scrollbar"
                      />
                      
                      <div className="absolute bottom-2 right-2 flex flex-col gap-1 items-end">
                        {/* 额外动作栏: 语音、上传图片 */}
                        <div className="flex bg-white rounded-full border border-slate-200 shadow-sm overflow-hidden mb-1">
                          <button 
                            onClick={toggleListening}
                            className={`p-1.5 transition-colors ${isListening ? 'text-red-500 bg-red-50' : 'text-slate-400 hover:text-slate-600 hover:bg-slate-50'}`}
                            title={isListening ? "停止语音输入" : "语音输入"}
                          >
                            {isListening ? <Mic size={14} className="animate-pulse" /> : <MicOff size={14} />}
                          </button>
                          
                          <label className="p-1.5 text-slate-400 hover:text-slate-600 hover:bg-slate-50 cursor-pointer transition-colors" title="上传本地图片">
                            <input type="file" accept="image/*" multiple className="hidden" onChange={handleAiLocalImageUpload} />
                            <ImagePlus size={14} />
                          </label>
                        </div>
                        
                        <button 
                          onClick={() => handleAIGenerate(chatInput)}
                          disabled={isGenerating || !chatInput.trim()}
                          className="p-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
                        >
                          {isGenerating ? <Loader2 size={16} className="animate-spin" /> : <Sparkles size={16} />}
                        </button>
                      </div>
                    </div>
                  </div>
                </div>
              )}
            </div>
          </aside>
        </div>
      </div>
      <canvas ref={canvasRef} className="hidden" />
    </div>
  );
}
