import React, { useEffect, useState, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import Sidebar from '../components/Sidebar';
import { Plus, Edit, Trash2, Save, Printer, Undo, Redo, Bold, Italic, Underline, AlignLeft, AlignCenter, AlignRight, Table, Image as ImageIcon, Bot, Check, Download, Upload } from 'lucide-react';
import { User, Template, FormField, FieldType, DEFAULT_FORM_FIELDS } from '../types';
import { defaultReportContent } from '../utils/defaultContent';
import { printDocument } from '../utils/print';
import { storage } from '../utils/storage';

export default function TemplateManage() {
  const navigate = useNavigate();
  const [currentUser, setCurrentUser] = useState<User | null>(null);
  const [templates, setTemplates] = useState<Template[]>([]);
  const [currentTemplateId, setCurrentTemplateId] = useState<string | null>(null);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [exportModalOpen, setExportModalOpen] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const [formData, setFormData] = useState({ name: '', desc: '' });
  const [importedContent, setImportedContent] = useState<{content: string; fields: FormField[]} | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [isSaved, setIsSaved] = useState(false);
  const editorRef = useRef<HTMLDivElement>(null);
  const savedRangeRef = useRef<Range | null>(null);
  const undoStack = useRef<string[]>([]);
  const redoStack = useRef<string[]>([]);
  const [fieldLibTab, setFieldLibTab] = useState<'insert' | 'manage'>('insert');
  const [formFields, setFormFields] = useState<FormField[]>([]);
  const [newFieldForm, setNewFieldForm] = useState({ label: '', category: '填空', type: 'text' as FieldType });
  const [newFieldOptions, setNewFieldOptions] = useState('');
  const [expandedCategories, setExpandedCategories] = useState<string[]>(['填空', '单选', '多选', '时间']);
  const [imagePickerOpen, setImagePickerOpen] = useState(false);
  const [imagePickerTarget, setImagePickerTarget] = useState<HTMLElement | null>(null);
  const [activeFieldKey, setActiveFieldKey] = useState<string | null>(null);
  const [editingFieldKey, setEditingFieldKey] = useState<string | null>(null);
  const [editFieldLabel, setEditFieldLabel] = useState('');
  const [editFieldOptions, setEditFieldOptions] = useState('');
  const [editFieldTimeFormat, setEditFieldTimeFormat] = useState('');
  const [editFieldTimeDefault, setEditFieldTimeDefault] = useState<'current' | 'specific'>('specific');
  const [editFieldFixedTimeValue, setEditFieldFixedTimeValue] = useState('');
  const [editFieldHasUnderline, setEditFieldHasUnderline] = useState(false);
  const [newFieldTimeFormat, setNewFieldTimeFormat] = useState('YYYY年MM月DD日');
  const [newFieldTimeDefault, setNewFieldTimeDefault] = useState<'current' | 'specific'>('specific');
  const [newFieldFixedTimeValue, setNewFieldFixedTimeValue] = useState('');
  const [newFieldHasUnderline, setNewFieldHasUnderline] = useState(false);
  const [customTimeFormats, setCustomTimeFormats] = useState<string[]>([]);
  const [formatDropdownOpen, setFormatDropdownOpen] = useState(false);
  const [newFormatDropdownOpen, setNewFormatDropdownOpen] = useState(false);
  const [placeholderModal, setPlaceholderModal] = useState({
    isOpen: false, width: '200', height: '200', mode: 'frame' as 'frame' | 'manual'
  });
  const [tableModal, setTableModal] = useState({
    isOpen: false, rows: '2', cols: '3'
  });
  const [imageAssets, setImageAssets] = useState<{ id: string; name: string; dataUrl: string }[]>([]);
  const [selectedIds, setSelectedIds] = useState<string[]>([]);

  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`;
  };

  useEffect(() => {
    const user = storage.get<User | null>('currentUser', null);
    if (!user || user.role === 'user') {
      navigate('/dashboard');
      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 savedAssets = storage.get<{ id: string; name: string; dataUrl: string }[]>('imageAssets', []);
    if (savedAssets.length > 0) {
      setImageAssets(savedAssets);
    } else {
      fetch('/logo_square.png')
        .then((res) => res.blob())
        .then((blob) => {
          const reader = new FileReader();
          reader.onloadend = () => {
            const dataUrl = reader.result as string;
            const initialAssets = [{ id: 'asset_logo', name: '医院Logo', dataUrl }];
            setImageAssets(initialAssets);
            storage.set('imageAssets', initialAssets);
          };
          reader.readAsDataURL(blob);
        })
        .catch(() => setImageAssets([]));
    }

    const savedFormats = storage.get<string[]>('customTimeFormats', []);
    const defaultFormats = ['YYYY-MM-DD', 'YYYY年MM月DD日', 'MM-DD', 'MM月DD日', 'HH:mm', 'hh:mm A'];
    const cleanedSaved = savedFormats.filter(f => f !== '24h' && f !== '12h');
    setCustomTimeFormats(Array.from(new Set([...defaultFormats, ...cleanedSaved])));

    const savedTemplates = storage.get<Template[]>('templates', []);
    if (savedTemplates.length === 0) {
      const initial: Template = {
        id: 'surgery',
        name: '腹腔镜胆囊切除术报告',
        desc: '标准手术记录模板',
        content: defaultReportContent,
        createdAt: new Date().toISOString(),
        author: 'admin'
      };
      setTemplates([initial]);
      storage.set('templates', [initial]);
      setCurrentTemplateId(initial.id);
    } else {
      const manageable = user.role === 'super'
        ? savedTemplates.map(t => t.id)
        : (Array.isArray(user.manageableTemplates) ? user.manageableTemplates : savedTemplates.map(t => t.id));
      const filtered = savedTemplates.filter(t => manageable.includes(t.id));
      setTemplates(filtered);
      setCurrentTemplateId(filtered[0]?.id || null);
    }
  }, [navigate]);

  useEffect(() => {
    if (currentTemplateId && editorRef.current) {
      const template = templates.find(t => t.id === currentTemplateId);
      if (template) {
        editorRef.current.innerHTML = template.content;
        if (template.fields && template.fields.length > 0) {
          setFormFields(template.fields);
          storage.set('formFieldsConfig', template.fields);
        }
      }
      setTimeout(() => updatePageHeight(), 0);
    }
  }, [currentTemplateId, templates]);

  useEffect(() => {
    if (!editorRef.current) return;
    const observer = new MutationObserver(() => {
      updatePageHeight();
    });
    observer.observe(editorRef.current, { childList: true, subtree: true, attributes: true, characterData: true });
    return () => observer.disconnect();
  }, [currentUser]);

  const fillPlaceholderSrc = (placeholder: HTMLElement, src: string) => {
    const mw = placeholder.style.maxWidth || placeholder.style.width || '200px';
    const mh = placeholder.style.maxHeight || placeholder.style.height || '200px';
    placeholder.innerHTML = `
      <span class="delete-btn" contenteditable="false">×</span>
      <img src="${src}" style="max-width:${mw};max-height:${mh};display:block;object-fit:contain;object-position:left top;" draggable="false">
    `;
    placeholder.classList.add('has-image');
    placeholder.style.border = 'none';
    placeholder.style.background = 'transparent';
    placeholder.style.width = 'auto';
    placeholder.style.height = 'auto';
    placeholder.style.lineHeight = 'normal';
    placeholder.style.maxWidth = mw;
    placeholder.style.maxHeight = mh;
    placeholder.style.textAlign = 'left';
    placeholder.style.verticalAlign = 'top';
    placeholder.style.justifyContent = 'flex-start';
    placeholder.style.alignItems = 'flex-start';
    saveTemplateContent();
  };

  // Handle image placeholder and smart field delete interactions via click capture
  useEffect(() => {
    const handleEditorClick = (e: MouseEvent) => {
      let node: Node | null = e.target as Node;
      if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;
      const targetEl = node as HTMLElement | null;
      if (!targetEl) return;

      const smartField = targetEl.closest('.smart-field-wrapper') as HTMLElement | null;
      if (smartField && targetEl.closest('.delete-btn')) {
        e.stopPropagation();
        e.preventDefault();
        pushHistory();
        const sel = window.getSelection();
        const range = document.createRange();
        range.selectNode(smartField);
        sel?.removeAllRanges();
        sel?.addRange(range);
        document.execCommand('delete');
        saveTemplateContent();
        return;
      }

      if (smartField) {
        const valueSpan = smartField.querySelector('.field-value');
        const fieldKey = valueSpan?.getAttribute('data-bind') || smartField.getAttribute('data-bind');
        if (fieldKey) {
          setActiveFieldKey(fieldKey);
          const field = formFields.find(f => f.key === fieldKey);
          if (field) {
            setExpandedCategories(prev => prev.includes(field.category) ? prev : [...prev, field.category]);
            setTimeout(() => {
              const el = document.getElementById(`sidebar-field-${fieldKey}`);
              el?.scrollIntoView({ behavior: 'smooth', block: 'center' });
            }, 50);
          }
        }
        return;
      }

      const placeholder = targetEl.closest('.image-placeholder') as HTMLElement | null;
      if (!placeholder) return;

      if (targetEl.closest('.delete-btn')) {
        e.stopPropagation();
        e.preventDefault();
        pushHistory();
        if (placeholder.classList.contains('has-image')) {
          placeholder.classList.remove('has-image');
          const w = parseInt(placeholder.style.maxWidth || placeholder.style.width || '0');
          const text = w > 0 && w < 80 ? '插图' : '插入/点击放置图片';
          placeholder.innerHTML = `
            <span class="delete-btn" contenteditable="false">×</span>
            <span class="placeholder-text" style="color:#94a3b8;font-size:11px;pointer-events:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:block;width:100%;text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;">${text}</span>
          `;
          placeholder.style.border = '1px dashed #cbd5e1';
          placeholder.style.background = '#f8fafc';
          const mw = placeholder.style.maxWidth;
          const mh = placeholder.style.maxHeight;
          if (mw) placeholder.style.width = mw;
          if (mh) {
            placeholder.style.height = mh;
            placeholder.style.lineHeight = mh;
          }
          placeholder.style.textAlign = 'center';
          placeholder.style.verticalAlign = 'middle';
          placeholder.style.justifyContent = 'center';
          placeholder.style.alignItems = 'center';
        } else {
          const range = document.createRange();
          range.selectNode(placeholder);
          const sel = window.getSelection();
          sel?.removeAllRanges();
          sel?.addRange(range);
          document.execCommand('delete');
        }
        return;
      }

      if (!placeholder.classList.contains('has-image')) {
        e.preventDefault();
        e.stopPropagation();
        setImagePickerTarget(placeholder);
        setImagePickerOpen(true);
      }
    };

    const editor = editorRef.current;
    if (editor) {
      editor.addEventListener('click', handleEditorClick, true);
    }
    return () => {
      if (editor) {
        editor.removeEventListener('click', handleEditorClick, true);
      }
    };
  }, [currentTemplateId, currentUser, formFields]);

  // Intercept Backspace/Delete next to smart fields to avoid whole-line deletion
  useEffect(() => {
    const editor = editorRef.current;
    if (!editor) return;

    const handleKeyDown = (e: KeyboardEvent) => {
      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'z') {
        e.preventDefault();
        if (e.shiftKey) {
          handleRedo();
        } else {
          handleUndo();
        }
        return;
      }
      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'y') {
        e.preventDefault();
        handleRedo();
        return;
      }
      if (e.key !== 'Backspace' && e.key !== 'Delete') return;
      const sel = window.getSelection();
      if (!sel || !sel.isCollapsed || sel.rangeCount === 0) return;
      const range = sel.getRangeAt(0);
      const node = range.startContainer;
      const offset = range.startOffset;

      let target: Element | null = null;

      if (node.nodeType === Node.TEXT_NODE) {
        if (e.key === 'Backspace' && offset === 0) {
          const prev = node.previousSibling;
          if (prev && prev.nodeType === Node.ELEMENT_NODE && (prev as Element).classList?.contains('smart-field-wrapper')) {
            target = prev as Element;
          }
        } else if (e.key === 'Delete' && offset === (node.textContent?.length || 0)) {
          const next = node.nextSibling;
          if (next && next.nodeType === Node.ELEMENT_NODE && (next as Element).classList?.contains('smart-field-wrapper')) {
            target = next as Element;
          }
        }
      } else if (node.nodeType === Node.ELEMENT_NODE) {
        const el = node as Element;
        if (e.key === 'Backspace' && offset > 0) {
          const prev = el.childNodes[offset - 1];
          if (prev && prev.nodeType === Node.ELEMENT_NODE && (prev as Element).classList?.contains('smart-field-wrapper')) {
            target = prev as Element;
          }
        } else if (e.key === 'Delete' && offset < el.childNodes.length) {
          const next = el.childNodes[offset];
          if (next && next.nodeType === Node.ELEMENT_NODE && (next as Element).classList?.contains('smart-field-wrapper')) {
            target = next as Element;
          }
        }
      }

      if (target) {
        e.preventDefault();
        pushHistory();
        const sel = window.getSelection();
        const range = document.createRange();
        range.selectNode(target);
        sel?.removeAllRanges();
        sel?.addRange(range);
        document.execCommand('delete');
        saveTemplateContent();
      }
    };

    editor.addEventListener('keydown', handleKeyDown, true);
    return () => {
      editor.removeEventListener('keydown', handleKeyDown, true);
    };
  }, [currentTemplateId]);

  const saveSelection = () => {
    const sel = window.getSelection();
    if (sel && sel.rangeCount > 0) {
      savedRangeRef.current = sel.getRangeAt(0);
    }
  };

  const restoreSelection = () => {
    if (!savedRangeRef.current) return;
    const sel = window.getSelection();
    sel?.removeAllRanges();
    sel?.addRange(savedRangeRef.current);
  };

  const pushHistory = () => {
    if (!editorRef.current) return;
    undoStack.current.push(editorRef.current.innerHTML);
    redoStack.current = [];
  };

  const handleUndo = () => {
    if (undoStack.current.length === 0 || !editorRef.current) return;
    redoStack.current.push(editorRef.current.innerHTML);
    const prev = undoStack.current.pop();
    if (prev !== undefined) {
      editorRef.current.innerHTML = prev;
      saveTemplateContent();
    }
  };

  const handleRedo = () => {
    if (redoStack.current.length === 0 || !editorRef.current) return;
    undoStack.current.push(editorRef.current.innerHTML);
    const next = redoStack.current.pop();
    if (next !== undefined) {
      editorRef.current.innerHTML = next;
      saveTemplateContent();
    }
  };

  const execCmd = (command: string, value: string | undefined = undefined) => {
    if (command !== 'undo' && command !== 'redo') {
      pushHistory();
    }
    editorRef.current?.focus();
    document.execCommand(command, false, value);
    editorRef.current?.focus();
  };

  const changeLineHeight = (height: string) => {
    const sel = window.getSelection();
    if (!sel || !sel.rangeCount) return;
    let node = sel.getRangeAt(0).commonAncestorContainer;
    if (node.nodeType === Node.TEXT_NODE) node = node.parentNode as Node;
    const block = (node as HTMLElement).closest('p, div, td, h1, h2, h3, li');
    if (block) {
      (block as HTMLElement).style.lineHeight = height;
      saveTemplateContent();
    }
  };

  const changeAlignment = (align: 'left' | 'center' | 'right' | 'justify') => {
    const sel = window.getSelection();
    if (!sel || !sel.rangeCount) return;
    let node = sel.getRangeAt(0).commonAncestorContainer;
    if (node.nodeType === Node.TEXT_NODE) node = node.parentNode as Node;
    const block = (node as HTMLElement).closest('p, div, td, h1, h2, h3, li');
    if (block) {
      (block as HTMLElement).style.textAlign = align;
      saveTemplateContent();
    }
  };

  const saveTemplateContent = () => {
    if (!currentTemplateId || !editorRef.current) return;
    let cleanContent = editorRef.current.innerHTML;
    cleanContent = cleanContent.replace(/<p>\s*<br\s*\/?>\s*<\/p>/gi, '');
    cleanContent = cleanContent.replace(/<p><\/p>/gi, '');
    cleanContent = cleanContent.replace(/>(\s+)</g, '><');
    if (cleanContent !== editorRef.current.innerHTML) {
      editorRef.current.innerHTML = cleanContent;
    }
    const allTemplates = storage.get<Template[]>('templates', []);
    const updated = allTemplates.map(t =>
      t.id === currentTemplateId ? { ...t, content: cleanContent, updatedAt: new Date().toISOString() } : t
    );
    setTemplates(prevTemplates => prevTemplates.map(t => updated.find(u => u.id === t.id) || t));
    storage.set('templates', updated);
  };

  const insertSmartField = (field: FormField) => {
    editorRef.current?.focus();
    restoreSelection();
    if (editorRef.current?.querySelector(`[data-bind="${field.key}"]`)) {
      alert(`字段 "${field.label}" 已存在，请勿重复插入。`);
      return;
    }
    pushHistory();

    const underlineClass = field.hasUnderline !== true ? ' no-underline' : '';
    const html = `<span class="smart-field-wrapper" contenteditable="false" style="white-space:nowrap;position:relative;"><span class="field-value${underlineClass}" data-bind="${field.key}" contenteditable="true" style="min-width:32px;padding:0 4px;margin:0 2px;border:1px solid #cbd5e1;border-radius:2px;display:inline-block;background:#f8fafc;color:#0f172a;line-height:1.2;font-size:inherit;vertical-align:text-bottom;box-sizing:border-box;min-height:1.2em;outline:none;"> </span><span class="delete-btn" contenteditable="false">×</span></span>&#8203;`;

    const sel = window.getSelection();
    if (sel && sel.rangeCount > 0) {
      const range = sel.getRangeAt(0);
      range.deleteContents();
      const wrapper = document.createElement('div');
      wrapper.innerHTML = html;
      const fragment = document.createDocumentFragment();
      while (wrapper.firstChild) {
        fragment.appendChild(wrapper.firstChild);
      }
      range.insertNode(fragment);

      const lastNode = fragment.lastChild;
      if (lastNode) {
        const newRange = document.createRange();
        newRange.setStartAfter(lastNode);
        newRange.collapse(true);
        sel.removeAllRanges();
        sel.addRange(newRange);
      }
    }

    editorRef.current?.focus();
    saveTemplateContent();
  };

  const highlightField = (key: string, active: boolean) => {
    if (!editorRef.current) return;
    const el = editorRef.current.querySelector(`[data-bind="${key}"]`) as HTMLElement | null;
    if (!el) return;
    if (active) {
      el.style.transition = 'all 0.2s';
      el.style.boxShadow = '0 0 0 2px #3b82f6';
      el.style.backgroundColor = '#e0f2fe';
    } else {
      el.style.boxShadow = '';
      el.style.backgroundColor = '';
    }
  };

  const toggleFieldVisible = (key: string) => {
    const updated = formFields.map(f => f.key === key ? { ...f, visibleInForm: !f.visibleInForm } : f);
    setFormFields(updated);
    storage.set('formFieldsConfig', updated);
  };

  const deleteField = (key: string) => {
    const updated = formFields.filter(f => f.key !== key);
    setFormFields(updated);
    storage.set('formFieldsConfig', updated);
  };

  const saveFieldEdit = (key: string) => {
    const updated = formFields.map(f => {
      if (f.key !== key) return f;
      const next: FormField = { ...f };
      if (!f.isSystemLocked) {
        next.label = editFieldLabel.trim() || f.label;
      }
      if (['单选', '多选', '图片'].includes(f.category)) {
        next.options = editFieldOptions.split(/[,，]/).map(s => s.trim()).filter(Boolean);
      }
      if (f.category === '时间') {
        next.timeFormat = editFieldTimeFormat;
        next.timeDefault = editFieldTimeDefault;
        next.fixedTimeValue = editFieldFixedTimeValue;
      }
      next.hasUnderline = editFieldHasUnderline;
      return next;
    });
    setFormFields(updated);
    storage.set('formFieldsConfig', updated);
    setEditingFieldKey(null);

    // 同步更新编辑器中已插入字段的 classList
    if (editorRef.current) {
      const els = editorRef.current.querySelectorAll(`.field-value[data-bind="${key}"]`);
      els.forEach(el => {
        if (editFieldHasUnderline) {
          el.classList.remove('no-underline');
        } else {
          el.classList.add('no-underline');
        }
      });
      saveTemplateContent();
    }
  };

  const addField = () => {
    if (!newFieldForm.label.trim()) return;
    const key = 'custom_' + Date.now();
    const newField: FormField = {
      key,
      label: newFieldForm.label.trim(),
      category: newFieldForm.category,
      type: newFieldForm.type,
      visibleInForm: true,
      isSystemLocked: false,
      hasUnderline: newFieldHasUnderline,
      options: ['单选', '多选'].includes(newFieldForm.category) && newFieldOptions.trim()
        ? newFieldOptions.split(/[,，]/).map(s => s.trim()).filter(Boolean)
        : undefined
    };
    if (newFieldForm.category === '时间') {
      newField.timeFormat = newFieldTimeFormat;
      newField.timeDefault = newFieldTimeDefault;
      newField.fixedTimeValue = newFieldFixedTimeValue;
    }
    const updated = [...formFields, newField];
    setFormFields(updated);
    storage.set('formFieldsConfig', updated);
    setNewFieldForm({ label: '', category: '填空', type: 'text' });
    setNewFieldOptions('');
    setNewFieldTimeFormat('YYYY年MM月DD日');
    setNewFieldTimeDefault('specific');
    setNewFieldFixedTimeValue('');
    setNewFieldHasUnderline(true);
  };

  const handleAssetUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (event) => {
      const dataUrl = event.target?.result as string;
      const asset = { id: 'asset_' + Date.now(), name: file.name, dataUrl };
      const updated = [...imageAssets, asset];
      setImageAssets(updated);
      storage.set('imageAssets', updated);
    };
    reader.readAsDataURL(file);
    e.target.value = '';
  };

  const insertTable = () => {
    editorRef.current?.focus();
    restoreSelection();
    pushHistory();
    setTableModal({ isOpen: true, rows: '2', cols: '3' });
  };

  const insertImage = () => {
    editorRef.current?.focus();
    restoreSelection();
    pushHistory();
    setPlaceholderModal({ isOpen: true, width: '200', height: '200', mode: 'frame' });
  };

  const insertAiRegion = () => {
    const name = window.prompt('请输入 AI 可编辑区域的名称（如：手术步骤、病灶描述）：');
    if (!name || !name.trim()) return;
    if (editorRef.current?.querySelector(`[data-ai-id="${name}"]`)) {
      window.alert('该区域名称已存在，请使用其他名称以保证 AI 定位准确。');
      return;
    }
    editorRef.current?.focus();
    // Insert ai-region HTML
    const html = `<div class="ai-region" data-ai-id="${name}" data-ai-title="${name}" style="border: 1px dashed #3b82f6; padding: 16px 12px 12px; margin: 8px 0; position: relative; min-height: 60px; background: #f8fafc; border-radius: 6px;"><div contenteditable="false" style="position: absolute; top: -10px; right: 10px; background: #3b82f6; color: white; font-size: 10px; padding: 2px 8px; border-radius: 12px; z-index: 10; user-select: none; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">${name}-AI可编辑区域</div><div class="ai-content" style="min-height: 20px;">&#8203;</div></div><p><br></p>`;
    document.execCommand('insertHTML', false, html);
    saveTemplateContent();
  };

  const saveCurrentTemplate = () => {
    if (!currentTemplateId || !editorRef.current) return;
    let cleanContent = editorRef.current.innerHTML;
    cleanContent = cleanContent.replace(/<p>\s*<br\s*\/?>\s*<\/p>/gi, '');
    cleanContent = cleanContent.replace(/<p><\/p>/gi, '');
    cleanContent = cleanContent.replace(/>(\s+)</g, '><');
    if (cleanContent !== editorRef.current.innerHTML) {
      editorRef.current.innerHTML = cleanContent;
    }
    const allTemplates = storage.get<Template[]>('templates', []);
    const updated = allTemplates.map(t => {
      if (t.id === currentTemplateId) {
        return { ...t, content: cleanContent, updatedAt: new Date().toISOString() };
      }
      return t;
    });
    setTemplates(updated.filter(t => templates.some(x => x.id === t.id)));
    storage.set('templates', updated);
    setIsSaved(true);
    setTimeout(() => setIsSaved(false), 3000);
  };

  const handleAddTemplate = () => {
    setIsEditing(false);
    setFormData({ name: '', desc: '' });
    setIsModalOpen(true);
  };

  const handleEditInfo = (template: Template) => {
    setIsEditing(true);
    setFormData({ name: template.name, desc: template.desc || '' });
    setIsModalOpen(true);
  };

  const handleDeleteTemplate = (id: string) => {
    if (window.confirm('确定要删除此模板吗？')) {
      const allTemplates = storage.get<Template[]>('templates', []);
      const updated = allTemplates.filter(t => t.id !== id);
      setTemplates(updated);
      storage.set('templates', updated);
      if (currentTemplateId === id) {
        setCurrentTemplateId(updated[0]?.id || null);
      }
      setSelectedIds(prev => prev.filter(sid => sid !== id));
    }
  };

  const handleBatchDelete = () => {
    if (selectedIds.length === 0) return;
    if (!window.confirm(`确定要删除选中的 ${selectedIds.length} 个模板吗？`)) return;
    const allTemplates = storage.get<Template[]>('templates', []);
    const updated = allTemplates.filter(t => !selectedIds.includes(t.id));
    setTemplates(updated);
    storage.set('templates', updated);
    if (currentTemplateId && selectedIds.includes(currentTemplateId)) {
      setCurrentTemplateId(updated[0]?.id || null);
    }
    setSelectedIds([]);
  };

  const handleBatchExport = () => {
    if (selectedIds.length === 0) return;
    const targets = templates.filter(t => selectedIds.includes(t.id));
    const ts = new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString().replace(/[:.]/g, '-').slice(0, 16);
    const exportData = {
      version: '1.0',
      type: 'surclaw_template_package_batch',
      templates: targets
    };
    const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `模板批量导出-${ts}.json`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleImportFile = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (event) => {
      try {
        const json = JSON.parse(event.target?.result as string);
        if (json.type !== 'surclaw_template_package') {
          alert('无效的模板包文件');
          return;
        }
        setFormData({ name: json.title || '', desc: json.description || '' });
        setImportedContent({
          content: json.content || '',
          fields: Array.isArray(json.fields) ? json.fields : []
        });
      } catch {
        alert('文件解析失败，请检查 JSON 格式');
      }
    };
    reader.readAsText(file);
    if (e.target) e.target.value = '';
  };

  const handleExportTemplate = (template: Template) => {
    const exportData = {
      version: '1.0',
      type: 'surclaw_template_package',
      title: template.name,
      description: template.desc || '',
      content: template.content,
      fields: template.fields || formFields
    };
    const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    const ts = new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString().replace(/[:.]/g, '-').slice(0, 16);
    a.download = `模板导出-${template.name}-${ts}.json`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleModalSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const allTemplates = storage.get<Template[]>('templates', []);
    if (isEditing) {
      const updated = allTemplates.map(t => {
        if (t.id === currentTemplateId) {
          return { ...t, name: formData.name, desc: formData.desc };
        }
        return t;
      });
      setTemplates(updated.filter(t => templates.some(x => x.id === t.id)));
      storage.set('templates', updated);
    } else {
      const newTpl: Template = {
        id: 'tpl_' + Date.now(),
        name: formData.name,
        desc: formData.desc,
        content: importedContent?.content || defaultReportContent,
        createdAt: new Date().toISOString(),
        author: currentUser?.username || 'admin',
        fields: importedContent?.fields || formFields
      };
      const updated = [...allTemplates, newTpl];
      setTemplates([...templates, newTpl]);
      storage.set('templates', updated);
      setCurrentTemplateId(newTpl.id);
      if (importedContent?.fields && importedContent.fields.length > 0) {
        setFormFields(importedContent.fields);
        storage.set('formFieldsConfig', importedContent.fields);
      }

      const savedUsers = storage.get<User[]>('users', []);
      let updatedUsers = savedUsers;
      if (currentUser?.role === 'super') {
        updatedUsers = savedUsers.map(u => {
          if (u.role === 'super') {
            const mt = [...(u.manageableTemplates || [])];
            const vt = [...(u.visibleTemplates || [])];
            if (!mt.includes(newTpl.id)) mt.push(newTpl.id);
            if (!vt.includes(newTpl.id)) vt.push(newTpl.id);
            return { ...u, manageableTemplates: mt, visibleTemplates: vt };
          }
          return u;
        });
      } else if (currentUser?.role === 'admin') {
        const dept = currentUser.department || '';
        updatedUsers = savedUsers.map(u => {
          if (u.username === currentUser.username) {
            const mt = [...(u.manageableTemplates || [])];
            const vt = [...(u.visibleTemplates || [])];
            if (!mt.includes(newTpl.id)) mt.push(newTpl.id);
            if (!vt.includes(newTpl.id)) vt.push(newTpl.id);
            return { ...u, manageableTemplates: mt, visibleTemplates: vt };
          }
          if (u.role === 'user' && u.department === dept) {
            const vt = [...(u.visibleTemplates || [])];
            if (!vt.includes(newTpl.id)) vt.push(newTpl.id);
            return { ...u, visibleTemplates: vt };
          }
          return u;
        });
      }
      storage.set('users', updatedUsers);
      const currentCached = updatedUsers.find(u => u.username === currentUser?.username);
      if (currentCached) {
        storage.set('currentUser', currentCached);
        setCurrentUser(currentCached);
      }
    }
    setIsModalOpen(false);
    setImportedContent(null);
  };

  if (!currentUser) return null;

  const currentTemplate = templates.find(t => t.id === currentTemplateId);

  return (
    <div className="flex h-screen bg-bg overflow-hidden">
      <Sidebar />
      
      {/* Template List Sidebar */}
      <aside className="w-72 bg-sidebar-bg border-r border-border flex flex-col shrink-0 overflow-hidden">
        <div className="p-6 border-b border-border flex items-center justify-between">
          <span className="text-sm font-bold text-text-main uppercase tracking-wider">模板列表</span>
          <button 
            onClick={handleAddTemplate}
            className="w-8 h-8 bg-accent text-white rounded-lg flex items-center justify-center hover:bg-blue-700 transition-colors shadow-sm"
          >
            <Plus size={16} />
          </button>
        </div>
        {selectedIds.length > 0 && (
          <div className="px-4 pt-3 pb-1 flex items-center justify-between bg-slate-50 border-b border-border">
            <span className="text-xs text-text-muted font-bold">已选中 {selectedIds.length} 项</span>
            <div className="flex gap-2">
              <button 
                onClick={handleBatchExport}
                className="px-2 py-1 rounded-md bg-blue-50 text-blue-600 text-[10px] font-bold hover:bg-blue-100 transition-colors"
              >
                批量导出
              </button>
              <button 
                onClick={handleBatchDelete}
                className="px-2 py-1 rounded-md bg-red-50 text-red-600 text-[10px] font-bold hover:bg-red-100 transition-colors"
              >
                批量删除
              </button>
            </div>
          </div>
        )}
        <div className="flex-1 overflow-y-auto p-4 space-y-2">
          {templates.map(tpl => (
            <div 
              key={tpl.id}
              onClick={() => setCurrentTemplateId(tpl.id)}
              className={`p-4 rounded-xl border transition-all group cursor-pointer ${
                currentTemplateId === tpl.id 
                  ? 'bg-white border-accent shadow-sm' 
                  : 'bg-transparent border-transparent hover:bg-white hover:border-border'
              }`}
            >
              <div className="flex items-start gap-2">
                <input
                  type="checkbox"
                  checked={selectedIds.includes(tpl.id)}
                  onChange={(e) => {
                    e.stopPropagation();
                    setSelectedIds(prev => e.target.checked ? [...prev, tpl.id] : prev.filter(id => id !== tpl.id));
                  }}
                  onClick={(e) => e.stopPropagation()}
                  className="mt-1 shrink-0"
                />
                <div className="flex-1 min-w-0">
                  <div className="flex justify-between items-start mb-1">
                    <div className={`text-sm font-bold ${currentTemplateId === tpl.id ? 'text-accent' : 'text-text-main'}`}>
                      {tpl.name}
                    </div>
                  </div>
                  <div className="text-[10px] text-text-muted line-clamp-1 mb-2">{tpl.desc || '无描述'}</div>
                  <div className="flex gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
                    <button 
                      onClick={(e) => { e.stopPropagation(); handleEditInfo(tpl); }}
                      className="px-2 py-1 rounded-md bg-slate-100 text-slate-600 text-[10px] font-bold hover:bg-slate-200 transition-colors"
                    >
                      编辑
                    </button>
                    <button 
                      onClick={(e) => { e.stopPropagation(); handleExportTemplate(tpl); }}
                      className="px-2 py-1 rounded-md bg-blue-50 text-blue-600 text-[10px] font-bold hover:bg-blue-100 transition-colors"
                    >
                      导出
                    </button>
                    <button 
                      onClick={(e) => { e.stopPropagation(); handleDeleteTemplate(tpl.id); }}
                      className="px-2 py-1 rounded-md bg-red-50 text-red-600 text-[10px] font-bold hover:bg-red-100 transition-colors"
                    >
                      删除
                    </button>
                  </div>
                </div>
              </div>
            </div>
          ))}
          {templates.length === 0 && (
            <div className="text-center text-text-muted text-sm py-8">暂无模板</div>
          )}
        </div>
      </aside>

      {/* Main Editor */}
      <div className="flex-1 flex flex-col overflow-hidden">
        <header className="h-20 bg-white border-b border-border flex items-center justify-between px-8 shrink-0">
          <div className="flex items-center gap-4">
            <div>
              <h1 className="text-lg font-bold text-text-main">模板管理</h1>
              <p className="text-[10px] text-text-muted mt-0.5 uppercase tracking-wider font-bold">
                {currentTemplate ? currentTemplate.name : '请选择模板'}
              </p>
            </div>
          </div>
          <div className="flex items-center gap-4">
            {isSaved && (
              <span className="text-xs text-green-600 font-bold flex items-center gap-1">
                <Check size={14} />
                已保存
              </span>
            )}
            <button 
              onClick={saveCurrentTemplate}
              className="btn-accent inline-flex items-center gap-2"
            >
              <Save size={16} />
              保存模板
            </button>
            <button 
              onClick={() => setExportModalOpen(true)}
              className="p-2.5 rounded-lg bg-slate-100 text-text-muted hover:bg-slate-200 transition-colors"
              title="下载"
            >
              <Download size={18} />
            </button>
            <button 
              onClick={() => editorRef.current && printDocument(editorRef.current.innerHTML)}
              className="p-2.5 rounded-lg bg-slate-100 text-text-muted hover:bg-slate-200 transition-colors"
              title="打印预览"
            >
              <Printer size={18} />
            </button>
          </div>
        </header>

        <div className="flex-1 flex overflow-hidden">
          {/* Editor Main */}
          <div className="flex-1 flex flex-col overflow-hidden">
            {/* Toolbar */}
            <div className="flex items-center gap-1 p-3 border-b border-border bg-slate-50 shrink-0 overflow-x-auto no-scrollbar">
              <div className="flex gap-1 pr-3 mr-3 border-r border-border">
                <button onMouseDown={(e) => e.preventDefault()} onClick={handleUndo} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white text-text-muted hover:text-text-main transition-colors" title="撤销"><Undo size={16} /></button>
                <button onMouseDown={(e) => e.preventDefault()} onClick={handleRedo} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white text-text-muted hover:text-text-main transition-colors" title="重做"><Redo size={16} /></button>
              </div>
              <div className="flex gap-1 pr-3 mr-3 border-r border-border">
                <select 
                  onMouseDown={(e) => e.preventDefault()}
                  onChange={(e) => { execCmd('fontName', e.target.value); e.target.value = ''; }}
                  className="h-9 px-3 border border-border rounded-lg text-xs bg-white cursor-pointer focus:outline-hidden focus:border-accent"
                >
                  <option value="">选择字体</option>
                  <option value="SimSun">宋体</option>
                  <option value="Microsoft YaHei">微软雅黑</option>
                  <option value="SimHei">黑体</option>
                  <option value="KaiTi">楷体</option>
                </select>
                <select
                  onMouseDown={(e) => e.preventDefault()}
                  onChange={(e) => { if (e.target.value) { execCmd('fontSize', e.target.value); } e.target.value = ''; }}
                  className="h-9 px-3 border border-border rounded-lg text-xs bg-white cursor-pointer focus:outline-hidden focus:border-accent"
                >
                  <option value="">字号</option>
                  <option value="3">12pt</option>
                  <option value="4">14pt</option>
                  <option value="5">18pt</option>
                  <option value="6">24pt</option>
                </select>
                <select
                  onMouseDown={(e) => e.preventDefault()}
                  onChange={(e) => { if (e.target.value) { changeLineHeight(e.target.value); } e.target.value = ''; }}
                  className="h-9 px-3 border border-border rounded-lg text-xs bg-white cursor-pointer focus:outline-hidden focus:border-accent"
                >
                  <option value="">行距</option>
                  <option value="1">1.0</option>
                  <option value="1.5">1.5</option>
                  <option value="2">2.0</option>
                </select>
              </div>
              <div className="flex gap-1 pr-3 mr-3 border-r border-border">
                <button onMouseDown={(e) => e.preventDefault()} onClick={() => execCmd('bold')} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white text-text-muted hover:text-text-main transition-colors" title="粗体"><Bold size={16} /></button>
                <button onMouseDown={(e) => e.preventDefault()} onClick={() => execCmd('italic')} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white text-text-muted hover:text-text-main transition-colors" title="斜体"><Italic size={16} /></button>
                <button onMouseDown={(e) => e.preventDefault()} onClick={() => execCmd('underline')} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white text-text-muted hover:text-text-main transition-colors" title="下划线"><Underline size={16} /></button>
                <div className="relative flex items-center">
                  <input 
                    type="color" 
                    onMouseDown={(e) => e.preventDefault()}
                    onChange={(e) => execCmd('foreColor', e.target.value)}
                    className="w-9 h-9 p-1.5 bg-transparent border-none cursor-pointer rounded-lg hover:bg-white transition-colors"
                    title="文字颜色"
                  />
                </div>
              </div>
              <div className="flex gap-1 pr-3 mr-3 border-r border-border">
                <button onMouseDown={(e) => e.preventDefault()} onClick={() => changeAlignment('left')} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white text-text-muted hover:text-text-main transition-colors" title="左对齐"><AlignLeft size={16} /></button>
                <button onMouseDown={(e) => e.preventDefault()} onClick={() => changeAlignment('center')} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white text-text-muted hover:text-text-main transition-colors" title="居中"><AlignCenter size={16} /></button>
                <button onMouseDown={(e) => e.preventDefault()} onClick={() => changeAlignment('right')} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white text-text-muted hover:text-text-main transition-colors" title="右对齐"><AlignRight size={16} /></button>
              </div>
              <div className="flex gap-1">
                <button onMouseDown={(e) => e.preventDefault()} onClick={insertTable} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white text-text-muted hover:text-text-main transition-colors" title="插入表格"><Table size={16} /></button>
                <button onMouseDown={(e) => e.preventDefault()} onClick={insertImage} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-white text-text-muted hover:text-text-main transition-colors" title="插入图片占位符"><ImageIcon size={16} /></button>
                <button onMouseDown={(e) => e.preventDefault()} onClick={insertAiRegion} className="w-9 h-9 flex items-center justify-center rounded-lg hover:bg-blue-50 text-blue-500 transition-colors" title="插入AI可编辑区域"><Bot size={16} /></button>
              </div>
            </div>

            {/* Editor Area */}
            <div className="editor-content-wrapper print-wrapper">
              <div 
                ref={editorRef}
                contentEditable
                className="editor-content print-content template-editor-mode"
                onBlur={saveSelection}
                onMouseUp={saveSelection}
                onKeyUp={saveSelection}
              >
              </div>
            </div>
          </div>

          {/* Right: Field Library */}
          <aside className="w-[240px] bg-sidebar-bg border-l border-border flex flex-col shrink-0 overflow-hidden">
            <div className="flex border-b border-border">
              {(['insert', 'manage'] as const).map(tab => (
                <button
                  key={tab}
                  onClick={() => setFieldLibTab(tab)}
                  className={`flex-1 py-3 text-xs font-bold transition-all border-b-2 uppercase tracking-wider ${
                    fieldLibTab === tab ? 'text-accent border-accent' : 'text-text-muted border-transparent hover:text-text-main'
                  }`}
                >
                  {tab === 'insert' ? '插入字段' : '字段管理'}
                </button>
              ))}
            </div>
            <div className="flex-1 overflow-y-auto p-4 space-y-3">
              {fieldLibTab === 'insert' && (
                <div className="space-y-4">
                  {['填空', '单选', '多选', '时间'].map(cat => {
                    const catFields = formFields.filter(f => f.category === cat);
                    if (catFields.length === 0) return null;
                    return (
                      <div key={cat}>
                        <div className="text-[10px] text-slate-400 mb-1.5 font-medium">{cat}</div>
                        <div className="flex flex-wrap gap-1.5">
                          {catFields.map(field => (
                            <button
                              key={field.key}
                              id={`sidebar-field-${field.key}`}
                              type="button"
                              onMouseDown={(e) => e.preventDefault()}
                              onClick={() => insertSmartField(field)}
                              onMouseEnter={() => highlightField(field.key, true)}
                              onMouseLeave={() => highlightField(field.key, false)}
                              className={`px-2 py-1 text-[11px] bg-slate-100 hover:bg-slate-200 text-slate-700 rounded border border-slate-300 transition-colors ${activeFieldKey === field.key ? 'ring-2 ring-accent bg-blue-50 border-accent' : ''}`}
                              title={`插入 ${field.label}`}
                            >
                              {field.label}
                            </button>
                          ))}
                        </div>
                      </div>
                    );
                  })}
                </div>
              )}

              {fieldLibTab === 'manage' && (
                <div className="space-y-3">
                  {['填空', '单选', '多选', '时间'].map(cat => {
                    const catFields = formFields.filter(f => f.category === cat);
                    if (catFields.length === 0) return null;
                    const expanded = expandedCategories.includes(cat);
                    return (
                      <div key={cat} className="border border-slate-200 rounded overflow-hidden">
                        <button
                          onClick={() => setExpandedCategories(prev => prev.includes(cat) ? prev.filter(c => c !== cat) : [...prev, cat])}
                          className="w-full flex items-center justify-between px-3 py-2 bg-slate-50 text-xs font-semibold text-slate-700 hover:bg-slate-100"
                        >
                          <span>{cat}</span>
                          <span>{expanded ? '▾' : '▸'}</span>
                        </button>
                        {expanded && (
                          <div className="p-2 space-y-2 bg-white">
                            {catFields.map(field => (
                              <div
                                key={field.key}
                                id={`sidebar-field-${field.key}`}
                                onClick={(e) => {
                                  setEditingFieldKey(field.key);
                                  setEditFieldLabel(field.label);
                                  setEditFieldOptions((field.options || []).join(', '));
                                  setEditFieldTimeFormat(field.timeFormat || '');
                                  setEditFieldTimeDefault(field.timeDefault || 'specific');
                                  setEditFieldFixedTimeValue(field.fixedTimeValue || '');
                    setEditFieldHasUnderline(field.hasUnderline ?? false);
                                  const target = e.currentTarget;
                                  setTimeout(() => {
                                    target.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
                                  }, 50);
                                }}
                                className={`cursor-pointer rounded border p-2 transition-all ${activeFieldKey === field.key ? 'border-accent bg-blue-50 ring-1 ring-accent' : 'border-slate-100 bg-slate-50 hover:border-slate-200'}`}
                              >
                                {editingFieldKey === field.key ? (
                                  <div className="space-y-2" onClick={(e) => e.stopPropagation()}>
                                    <div className="text-xs font-medium text-text-main">
                                      {field.isSystemLocked ? field.label : (
                                        <input
                                          type="text"
                                          value={editFieldLabel}
                                          onChange={(e) => setEditFieldLabel(e.target.value)}
                                          className="w-full px-1.5 py-1 text-xs border border-border rounded"
                                          placeholder="字段名称"
                                        />
                                      )}
                                    </div>
                                    {['单选', '多选'].includes(field.category) && (
                                      <input
                                        type="text"
                                        value={editFieldOptions}
                                        onChange={(e) => setEditFieldOptions(e.target.value)}
                                        className="w-full px-1.5 py-1 text-xs border border-border rounded"
                                        placeholder="选项，用逗号分隔"
                                      />
                                    )}
                                    {field.category === '时间' && (
                                      <div className="space-y-1">
                                        <select
                                          value={editFieldTimeDefault}
                                          onChange={(e) => setEditFieldTimeDefault(e.target.value as 'current' | 'specific')}
                                          className="w-full px-1.5 py-1 text-xs border border-border rounded bg-white"
                                        >
                                          <option value="specific">固定时间</option>
                                          <option value="current">当前时间</option>
                                        </select>
                                        {editFieldTimeDefault === 'specific' && (
                                          <input
                                            type={field.type === 'date' ? 'date' : 'time'}
                                            value={editFieldFixedTimeValue}
                                            onChange={(e) => setEditFieldFixedTimeValue(e.target.value)}
                                            className="w-full px-1.5 py-1 text-xs border border-border rounded"
                                          />
                                        )}
                                        <div className="relative">
                                          <input
                                            type="text"
                                            value={editFieldTimeFormat}
                                            onChange={(e) => setEditFieldTimeFormat(e.target.value)}
                                            onFocus={() => setFormatDropdownOpen(true)}
                                            onBlur={() => {
                                              setTimeout(() => setFormatDropdownOpen(false), 200);
                                              const val = editFieldTimeFormat.trim();
                                              if (val && !customTimeFormats.includes(val)) {
                                                const next = [...customTimeFormats, val];
                                                setCustomTimeFormats(next);
                                                storage.set('customTimeFormats', next);
                                              }
                                            }}
                                            onKeyDown={(e) => {
                                              if (e.key === 'Enter') {
                                                const val = editFieldTimeFormat.trim();
                                                if (val && !customTimeFormats.includes(val)) {
                                                  const next = [...customTimeFormats, val];
                                                  setCustomTimeFormats(next);
                                                  storage.set('customTimeFormats', next);
                                                }
                                                setFormatDropdownOpen(false);
                                              }
                                            }}
                                            className="w-full px-1.5 py-1 text-xs border border-border rounded"
                                            placeholder="输入格式或下拉选择"
                                          />
                                          {formatDropdownOpen && (
                                            <div className="absolute z-10 left-0 right-0 top-full mt-1 bg-white border border-border rounded shadow-lg max-h-32 overflow-y-auto">
                                              {customTimeFormats
                                                .filter(fmt => {
                                                  const isDateFormat = /YYYY|MM|DD/.test(fmt);
                                                  const isTimeFormat = /HH|hh|mm|A/.test(fmt);
                                                  if (field.type === 'date') return isDateFormat;
                                                  if (field.type === 'time') return isTimeFormat;
                                                  return true;
                                                })
                                                .map(fmt => (
                                                  <div
                                                    key={fmt}
                                                    className="px-2 py-1 text-xs hover:bg-slate-100 cursor-pointer"
                                                    onMouseDown={(e) => {
                                                      e.preventDefault();
                                                      setEditFieldTimeFormat(fmt);
                                                      setFormatDropdownOpen(false);
                                                    }}
                                                  >
                                                    {fmt}
                                                  </div>
                                                ))}
                                            </div>
                                          )}
                                        </div>
                                      </div>
                                    )}
                                    <label className="flex items-center gap-1 text-[10px] text-slate-600 cursor-pointer">
                                      <input type="checkbox" checked={editFieldHasUnderline} onChange={(e) => setEditFieldHasUnderline(e.target.checked)} />
                                      打印时显示下划线
                                    </label>
                                    <div className="flex gap-2">
                                      <button
                                        onClick={() => saveFieldEdit(field.key)}
                                        className="px-2 py-1 bg-accent text-white text-[10px] rounded"
                                      >保存</button>
                                      <button
                                        onClick={() => setEditingFieldKey(null)}
                                        className="px-2 py-1 bg-slate-200 text-slate-700 text-[10px] rounded"
                                      >取消</button>
                                    </div>
                                  </div>
                                ) : (
                                  <div className="flex items-center justify-between">
                                    <div>
                                      <div className="font-medium text-text-main text-xs">{field.label}</div>
                                      <div className="text-[10px] text-slate-400">{field.category} · {field.type}</div>
                                    </div>
                                    <div className="flex items-center gap-2">
                                      <label className="flex items-center gap-1 text-[10px] text-slate-600 cursor-pointer" onClick={(e) => e.stopPropagation()}>
                                        <input
                                          type="checkbox"
                                          checked={field.visibleInForm}
                                          onChange={() => toggleFieldVisible(field.key)}
                                        />
                                        显示
                                      </label>
                                      {!field.isSystemLocked && (
                                        <button onClick={(e) => { e.stopPropagation(); deleteField(field.key); }} className="text-red-500 text-[10px] hover:underline">删除</button>
                                      )}
                                    </div>
                                  </div>
                                )}
                              </div>
                            ))}
                          </div>
                        )}
                      </div>
                    );
                  })}

                  {/* Asset Library */}
                  <div className="border border-slate-200 rounded overflow-hidden mt-4">
                    <div className="px-3 py-2 bg-slate-50 text-xs font-semibold text-slate-700">素材库</div>
                    <div className="p-2 space-y-2 bg-white">
                      <div className="flex flex-wrap gap-2">
                        {imageAssets.map(asset => (
                          <div key={asset.id} className="relative w-14 h-14 border rounded overflow-hidden group">
                            <img src={asset.dataUrl} alt={asset.name} className="w-full h-full object-cover" />
                            <div className="absolute inset-0 bg-black/40 hidden group-hover:flex items-center justify-center">
                              <button
                                onClick={() => {
                                  const updated = imageAssets.filter(a => a.id !== asset.id);
                                  setImageAssets(updated);
                                  storage.set('imageAssets', updated);
                                }}
                                className="text-white text-[10px]"
                              >删</button>
                            </div>
                          </div>
                        ))}
                      </div>
                      <label className="block w-full py-1.5 bg-accent text-white text-xs font-semibold rounded text-center cursor-pointer hover:opacity-90">
                        上传图片
                        <input type="file" accept="image/*" className="hidden" onChange={handleAssetUpload} />
                      </label>
                    </div>
                  </div>

                  <div className="pt-3 border-t border-slate-200 space-y-2">
                    <div className="text-xs font-semibold text-text-main">新增字段</div>
                    <input
                      type="text"
                      value={newFieldForm.label}
                      onChange={(e) => setNewFieldForm({ ...newFieldForm, label: e.target.value })}
                      placeholder="字段名称"
                      className="w-full px-2 py-1.5 text-xs border border-border rounded focus:outline-hidden focus:border-accent"
                    />
                    <div className="flex gap-2">
                      <select
                        value={newFieldForm.category}
                        onChange={(e) => {
                          const cat = e.target.value;
                          let t: FieldType = 'text';
                          if (cat === '单选') t = 'single_select';
                          else if (cat === '多选') t = 'multi_select';
                          else if (cat === '时间') t = 'date';
                          setNewFieldForm({ ...newFieldForm, category: cat, type: t });
                        }}
                        className="flex-1 px-2 py-1.5 text-xs border border-border rounded focus:outline-hidden focus:border-accent bg-white"
                      >
                        <option value="填空">填空</option>
                        <option value="单选">单选</option>
                        <option value="多选">多选</option>
                        <option value="时间">时间</option>
                      </select>
                      <select
                        value={newFieldForm.type}
                        onChange={(e) => {
                          const t = e.target.value as FieldType;
                          setNewFieldForm({ ...newFieldForm, type: t });
                          if (newFieldForm.category === '时间') {
                            setNewFieldTimeFormat(t === 'date' ? 'YYYY年MM月DD日' : 'HH:mm');
                          }
                        }}
                        className="flex-1 px-2 py-1.5 text-xs border border-border rounded focus:outline-hidden focus:border-accent bg-white"
                      >
                        {newFieldForm.category === '填空' && <option value="text">文本</option>}
                        {newFieldForm.category === '单选' && <option value="single_select">下拉单选</option>}
                        {newFieldForm.category === '多选' && <option value="multi_select">标签多选</option>}
                        {newFieldForm.category === '时间' && <><option value="date">日期</option><option value="time">时分</option></>}
                      </select>
                    </div>
                    {newFieldForm.category === '时间' && (
                      <div className="space-y-1">
                        <select
                          value={newFieldTimeDefault}
                          onChange={(e) => setNewFieldTimeDefault(e.target.value as 'current' | 'specific')}
                          className="w-full px-2 py-1.5 text-xs border border-border rounded bg-white"
                        >
                          <option value="specific">固定时间</option>
                          <option value="current">当前时间</option>
                        </select>
                        {newFieldTimeDefault === 'specific' && (
                          <input
                            type={newFieldForm.type === 'date' ? 'date' : 'time'}
                            value={newFieldFixedTimeValue}
                            onChange={(e) => setNewFieldFixedTimeValue(e.target.value)}
                            className="w-full px-2 py-1.5 text-xs border border-border rounded"
                          />
                        )}
                        <div className="relative">
                          <input
                            type="text"
                            value={newFieldTimeFormat}
                            onChange={(e) => setNewFieldTimeFormat(e.target.value)}
                            onFocus={() => setNewFormatDropdownOpen(true)}
                            onBlur={() => {
                              setTimeout(() => setNewFormatDropdownOpen(false), 200);
                              const val = newFieldTimeFormat.trim();
                              if (val && !customTimeFormats.includes(val)) {
                                const next = [...customTimeFormats, val];
                                setCustomTimeFormats(next);
                                storage.set('customTimeFormats', next);
                              }
                            }}
                            onKeyDown={(e) => {
                              if (e.key === 'Enter') {
                                const val = newFieldTimeFormat.trim();
                                if (val && !customTimeFormats.includes(val)) {
                                  const next = [...customTimeFormats, val];
                                  setCustomTimeFormats(next);
                                  storage.set('customTimeFormats', next);
                                }
                                setNewFormatDropdownOpen(false);
                              }
                            }}
                            className="w-full px-2 py-1.5 text-xs border border-border rounded"
                            placeholder="输入格式或下拉选择"
                          />
                          {newFormatDropdownOpen && (
                            <div className="absolute z-10 left-0 right-0 top-full mt-1 bg-white border border-border rounded shadow-lg max-h-32 overflow-y-auto">
                              {customTimeFormats
                                .filter(fmt => {
                                  const isDateFormat = /YYYY|MM|DD/.test(fmt);
                                  const isTimeFormat = /HH|hh|mm|A/.test(fmt);
                                  if (newFieldForm.type === 'date') return isDateFormat;
                                  if (newFieldForm.type === 'time') return isTimeFormat;
                                  return true;
                                })
                                .map(fmt => (
                                  <div
                                    key={fmt}
                                    className="px-2 py-1 text-xs hover:bg-slate-100 cursor-pointer"
                                    onMouseDown={(e) => {
                                      e.preventDefault();
                                      setNewFieldTimeFormat(fmt);
                                      setNewFormatDropdownOpen(false);
                                    }}
                                  >
                                    {fmt}
                                  </div>
                                ))}
                            </div>
                          )}
                        </div>
                      </div>
                    )}
                    {['单选', '多选'].includes(newFieldForm.category) && (
                      <input
                        type="text"
                        value={newFieldOptions}
                        onChange={(e) => setNewFieldOptions(e.target.value)}
                        placeholder="选项，用逗号分隔"
                        className="w-full px-2 py-1.5 text-xs border border-border rounded focus:outline-hidden focus:border-accent"
                      />
                    )}
                    <label className="flex items-center gap-1 text-xs text-slate-600 cursor-pointer">
                      <input type="checkbox" checked={newFieldHasUnderline} onChange={(e) => setNewFieldHasUnderline(e.target.checked)} />
                      打印时显示下划线
                    </label>
                    <button
                      onClick={addField}
                      className="w-full py-1.5 bg-accent text-white text-xs font-semibold rounded hover:opacity-90 transition-colors"
                    >
                      添加字段
                    </button>
                  </div>
                </div>
              )}
            </div>
          </aside>
        </div>
      </div>

      {exportModalOpen && (
        <div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4 backdrop-blur-sm">
          <div className="bg-white rounded-2xl p-6 w-full max-w-[360px] shadow-2xl border border-border">
            <h3 className="text-lg font-bold text-text-main mb-4">导出模板</h3>
            <div className="space-y-3">
              <button
                onClick={() => {
                  const ts = new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString().replace(/[:.]/g, '-').slice(0, 16);
                  const name = currentTemplate?.name || '模板';
                  printDocument(editorRef.current?.innerHTML || '', `${name}-${ts}`);
                  setExportModalOpen(false);
                }}
                className="w-full py-2.5 bg-accent text-white rounded text-sm font-semibold hover:opacity-90 transition-colors"
              >导出 PDF</button>
              <button
                onClick={() => {
                  const ts = new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString().replace(/[:.]/g, '-').slice(0, 16);
                  const name = currentTemplate?.name || '模板';
                  const data = currentTemplate ? { ...currentTemplate, content: editorRef.current?.innerHTML } : { content: editorRef.current?.innerHTML };
                  const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
                  const url = URL.createObjectURL(blob);
                  const a = document.createElement('a');
                  a.href = url;
                  a.download = `${name}-${ts}.json`;
                  a.click();
                  URL.revokeObjectURL(url);
                  setExportModalOpen(false);
                }}
                className="w-full py-2.5 bg-slate-100 text-slate-700 rounded text-sm font-semibold hover:bg-slate-200 transition-colors"
              >导出 JSON</button>
              <button
                onClick={() => setExportModalOpen(false)}
                className="w-full py-2.5 border border-border text-text-main rounded text-sm font-semibold hover:bg-slate-50 transition-colors"
              >取消</button>
            </div>
          </div>
        </div>
      )}

      {isModalOpen && (
        <div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4 backdrop-blur-sm">
          <div className="bg-white rounded-2xl p-10 w-full max-w-[500px] shadow-2xl border border-border">
            <h3 className="text-xl font-bold text-text-main mb-2">{isEditing ? '编辑模板信息' : '新增模板'}</h3>
            <p className="text-sm text-text-muted mb-8">设置模板的基本名称和描述</p>
            {!isEditing && (
              <div className="flex items-center gap-3 mb-6 p-3 bg-slate-50 rounded-xl border border-dashed border-slate-200">
                <div className="text-xs text-text-muted flex-1">已有模板文件？点击右侧图标导入</div>
                <button
                  type="button"
                  onClick={() => fileInputRef.current?.click()}
                  className="w-8 h-8 bg-accent text-white rounded-lg flex items-center justify-center hover:bg-blue-700 transition-colors shadow-sm"
                >
                  <Upload size={16} />
                </button>
                <input ref={fileInputRef} type="file" accept=".json" className="hidden" onChange={handleImportFile} />
              </div>
            )}
            <form onSubmit={handleModalSubmit} className="space-y-6">
              <div className="space-y-1.5">
                <label className="block text-xs font-bold text-text-main uppercase tracking-wider">模板名称 *</label>
                <input 
                  type="text" 
                  value={formData.name}
                  onChange={(e) => setFormData({ ...formData, name: e.target.value })}
                  required 
                  placeholder="请输入模板名称"
                  className="input-minimal"
                />
              </div>
              <div className="space-y-1.5">
                <label className="block text-xs font-bold text-text-main uppercase tracking-wider">模板描述</label>
                <textarea 
                  value={formData.desc}
                  onChange={(e) => setFormData({ ...formData, desc: e.target.value })}
                  placeholder="请输入模板描述"
                  className="input-minimal min-h-[100px] resize-y"
                />
              </div>
              <div className="flex justify-end gap-3 pt-4 border-t border-border">
                <button 
                  type="button" 
                  onClick={() => { setIsModalOpen(false); setImportedContent(null); }}
                  className="px-6 py-2.5 bg-slate-100 text-text-muted rounded-lg text-sm font-semibold hover:bg-slate-200 transition-colors"
                >
                  取消
                </button>
                <button 
                  type="submit" 
                  className="btn-accent"
                >
                  保存模板信息
                </button>
              </div>
            </form>
          </div>
        </div>
      )}

      {placeholderModal.isOpen && (
        <div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4 backdrop-blur-sm">
          <div className="bg-white rounded-2xl p-6 w-full max-w-[360px] shadow-2xl border border-border">
            <h3 className="text-lg font-bold text-text-main mb-4">插入图片占位符</h3>
            <div className="space-y-3">
              <div className="flex gap-2">
                <div className="flex-1">
                  <label className="block text-xs mb-1">宽度(px)</label>
                  <input type="number" value={placeholderModal.width} onChange={e => setPlaceholderModal({...placeholderModal, width: e.target.value})} className="w-full px-2 py-1 text-xs border border-border rounded" />
                </div>
                <div className="flex-1">
                  <label className="block text-xs mb-1">高度(px)</label>
                  <input type="number" value={placeholderModal.height} onChange={e => setPlaceholderModal({...placeholderModal, height: e.target.value})} className="w-full px-2 py-1 text-xs border border-border rounded" />
                </div>
              </div>
              <div>
                <label className="block text-xs mb-1">占位符类型</label>
                <div className="flex gap-2">
                  <button onClick={() => setPlaceholderModal({...placeholderModal, mode: 'frame'})} className={`flex-1 py-1.5 text-xs rounded border ${placeholderModal.mode === 'frame' ? 'bg-accent text-white border-accent' : 'bg-white text-slate-600 border-border'}`}>手术影像占位<br/><span className="text-[10px] opacity-80">（支持自动/拖拽插入）</span></button>
                  <button onClick={() => setPlaceholderModal({...placeholderModal, mode: 'manual'})} className={`flex-1 py-1.5 text-xs rounded border ${placeholderModal.mode === 'manual' ? 'bg-accent text-white border-accent' : 'bg-white text-slate-600 border-border'}`}>静态图片占位<br/><span className="text-[10px] opacity-80">（仅支持点击插入）</span></button>
                </div>
              </div>
            </div>
            <div className="mt-5 flex justify-end gap-2">
              <button onClick={() => setPlaceholderModal({...placeholderModal, isOpen: false})} className="px-4 py-2 bg-slate-100 text-slate-600 rounded text-sm">取消</button>
              <button onClick={() => {
                const sel = window.getSelection();
                let node: Node | null = sel?.anchorNode ?? null;
                let inTable = false;
                while (node) {
                  if ((node as Element).nodeName === 'TD' || (node as Element).nodeName === 'TH') {
                    inTable = true;
                    break;
                  }
                  node = node.parentNode;
                }
                const w = parseInt(placeholderModal.width) || 200;
                const h = parseInt(placeholderModal.height) || 200;
                const modeAttr = placeholderModal.mode === 'manual' ? ' data-mode="manual"' : '';
                const hintText = '插入/点击放置图片';
                const id = 'ph_' + Date.now();
                let html: string;
                if (inTable) {
                  const styleStr = 'position:relative;display:flex;align-items:center;justify-content:center;border:1px dashed #cbd5e1;background:#f8fafc;cursor:pointer;width:100%;height:100%;max-width:200px;max-height:200px;min-height:60px;margin:0 auto;';
                  html = `<div id="${id}" class="image-placeholder" data-placeholder="true" contenteditable="false"${modeAttr} style="${styleStr}"><span class="delete-btn" contenteditable="false">×</span><span class="placeholder-text" style="color:#94a3b8;font-size:11px;pointer-events:none;position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);display:block;width:100%;text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;">${hintText}</span></div>`;
                } else {
                  let styleStr = 'display:inline-block;text-align:center;border:1px dashed #cbd5e1;background:#f8fafc;vertical-align:middle;margin:0 4px;cursor:pointer;position:relative;';
                  styleStr += `width:${w}px;height:${h}px;max-width:${w}px;max-height:${h}px;line-height:${h}px;`;
                  const showShortText = w > 0 && w < 80;
                  const text = showShortText ? '插图' : hintText;
                  html = `<span id="${id}" class="image-placeholder" data-placeholder="true" contenteditable="false"${modeAttr} style="${styleStr}"><span class="delete-btn" contenteditable="false">×</span><span class="placeholder-text" style="color:#94a3b8;font-size:11px;pointer-events:none;position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);display:block;width:100%;text-align:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;">${text}</span></span>&#8203;`;
                }
                const wrapper = document.createElement('div');
                wrapper.innerHTML = html;
                const fragment = document.createDocumentFragment();
                while (wrapper.firstChild) {
                  fragment.appendChild(wrapper.firstChild);
                }
                const sel2 = window.getSelection();
                if (sel2 && sel2.rangeCount > 0) {
                  const range = sel2.getRangeAt(0);
                  range.deleteContents();
                  range.insertNode(fragment);
                  const lastNode = fragment.lastChild;
                  if (lastNode) {
                    range.setStartAfter(lastNode);
                    range.collapse(true);
                    sel2.removeAllRanges();
                    sel2.addRange(range);
                  }
                } else if (editorRef.current) {
                  editorRef.current.appendChild(fragment);
                }
                editorRef.current?.focus();
                saveTemplateContent();
                setPlaceholderModal({...placeholderModal, isOpen: false});
              }} className="px-4 py-2 bg-accent text-white rounded text-sm">确认插入</button>
            </div>
          </div>
        </div>
      )}

      {tableModal.isOpen && (
        <div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4 backdrop-blur-sm">
          <div className="bg-white rounded-2xl p-6 w-full max-w-[360px] shadow-2xl border border-border">
            <h3 className="text-lg font-bold text-text-main mb-4">插入表格</h3>
            <div className="space-y-3">
              <div className="flex gap-2">
                <div className="flex-1">
                  <label className="block text-xs mb-1">行数</label>
                  <input type="number" min="1" value={tableModal.rows} onChange={e => setTableModal({...tableModal, rows: e.target.value})} className="w-full px-2 py-1 text-xs border border-border rounded" />
                </div>
                <div className="flex-1">
                  <label className="block text-xs mb-1">列数</label>
                  <input type="number" min="1" value={tableModal.cols} onChange={e => setTableModal({...tableModal, cols: e.target.value})} className="w-full px-2 py-1 text-xs border border-border rounded" />
                </div>
              </div>
            </div>
            <div className="mt-5 flex justify-end gap-2">
              <button onClick={() => setTableModal({...tableModal, isOpen: false})} className="px-4 py-2 bg-slate-100 text-slate-600 rounded text-sm">取消</button>
              <button onClick={() => {
                const rows = parseInt(tableModal.rows);
                const cols = parseInt(tableModal.cols);
                if (isNaN(rows) || isNaN(cols) || rows < 1 || cols < 1) {
                  setTableModal({...tableModal, isOpen: false});
                  return;
                }
                let table = '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; table-layout: fixed;">';
                for (let i = 0; i < rows; i++) {
                  table += '<tr>';
                  for (let j = 0; j < cols; j++) {
                    table += '<td style="padding: 8px; border: 1px solid #e2e8f0; vertical-align: top;">单元格</td>';
                  }
                  table += '</tr>';
                }
                table += '</table><p></p>';
                execCmd('insertHTML', table);
                setTableModal({...tableModal, isOpen: false});
              }} className="px-4 py-2 bg-accent text-white rounded text-sm">确认插入</button>
            </div>
          </div>
        </div>
      )}

      {imagePickerOpen && imagePickerTarget && (
        <div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4 backdrop-blur-sm">
          <div className="bg-white rounded-2xl p-6 w-full max-w-[360px] shadow-2xl border border-border">
            <h3 className="text-lg font-bold text-text-main mb-4">选择图片来源</h3>
            <div className="space-y-3">
              <button
                onClick={() => {
                  const input = document.createElement('input');
                  input.type = 'file';
                  input.accept = 'image/*';
                  input.onchange = (ev) => {
                    const file = (ev.target as HTMLInputElement).files?.[0];
                    if (file) {
                      const reader = new FileReader();
                      reader.onload = (event) => {
                        const src = event.target?.result as string;
                        fillPlaceholderSrc(imagePickerTarget, src);
                        setImagePickerOpen(false);
                        setImagePickerTarget(null);
                      };
                      reader.readAsDataURL(file);
                    }
                  };
                  input.click();
                }}
                className="w-full py-2 bg-slate-100 hover:bg-slate-200 text-slate-700 rounded text-sm font-semibold"
              >本地上传</button>
              <button
                onClick={() => {
                  if (currentUser?.signature) {
                    fillPlaceholderSrc(imagePickerTarget, currentUser.signature);
                  }
                  setImagePickerOpen(false);
                  setImagePickerTarget(null);
                }}
                disabled={!currentUser?.signature}
                className={`w-full py-2 rounded text-sm font-semibold ${currentUser?.signature ? 'bg-slate-100 hover:bg-slate-200 text-slate-700' : 'bg-slate-50 text-slate-400 cursor-not-allowed'}`}
              >我的签名 {!currentUser?.signature && '(未上传)'}</button>
              <div>
                <div className="text-xs text-slate-500 mb-2">系统素材</div>
                <div className="flex flex-wrap gap-2 max-h-32 overflow-y-auto">
                  {imageAssets.map(asset => (
                    <button
                      key={asset.id}
                      onClick={() => { fillPlaceholderSrc(imagePickerTarget, asset.dataUrl); setImagePickerOpen(false); setImagePickerTarget(null); }}
                      className="w-16 h-16 border rounded overflow-hidden hover:ring-2 ring-accent"
                    >
                      <img src={asset.dataUrl} alt={asset.name} className="w-full h-full object-cover" />
                    </button>
                  ))}
                  {imageAssets.length === 0 && <div className="text-xs text-slate-400">暂无素材</div>}
                </div>
              </div>
            </div>
            <div className="mt-5 flex justify-end">
              <button onClick={() => { setImagePickerOpen(false); setImagePickerTarget(null); }} className="px-4 py-2 bg-slate-100 text-slate-600 rounded text-sm">取消</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
