import React, { useState, useEffect } from 'react';
import usePresetStore from '../../../../Store/SideBarLeft/PresetSlice';
import './Presets.css';

const PresetPanel = () => {
  const {
    selectedPreset,
    parameters,
    presets,
    isLoadingPresets,
    promptComponents,
    currentPage,
    pageSize,
    setSelectedPreset,
    updateParameter,
    saveCurrentAsPreset,
    editPresetName: updatePresetName,
    isParametersExpanded,
    toggleParametersExpanded,
    fetchPresets,
    setPromptComponents,
    toggleComponentEnabled,
    updateComponent,
    addComponent,
    removeComponent,
    moveComponent,
    saveComponentOrder,
    setCurrentPage,
    setPageSize,
    getCurrentPagePresets,
    getTotalPages
  } = usePresetStore();

  const [showSaveDialog, setShowSaveDialog] = useState(false);
  const [showEditDialog, setShowEditDialog] = useState(false);
  const [showComponentEditDialog, setShowComponentEditDialog] = useState(false);
  const [showActionsMenu, setShowActionsMenu] = useState(false);
  const [newPresetName, setNewPresetName] = useState('');
  const [editPresetId, setEditPresetId] = useState('');
  const [editPresetName, setEditPresetName] = useState('');
  const [tooltip, setTooltip] = useState({ visible: false, content: '', x: 0, y: 0 });

  // 组件编辑状态
  const [editingComponentIndex, setEditingComponentIndex] = useState(-1);
  const [editComponentName, setEditComponentName] = useState(''); // ✅ 新增：组件名称
  const [editComponentContent, setEditComponentContent] = useState('');
  const [editComponentRole, setEditComponentRole] = useState(0); // 0=system, 1=user, 2=ai
  const [isEditing, setIsEditing] = useState(false);

  // 拖拽状态
  const [draggedItem, setDraggedItem] = useState(null);
  const [dragOverItem, setDragOverItem] = useState(null);
  
  // 下拉菜单位置
  const [dropdownPosition, setDropdownPosition] = useState({ top: 0, right: 0 });
  
  // ✅ 页码跳转输入
  const [jumpPageInput, setJumpPageInput] = useState('');
  
  // 点击外部关闭下拉菜单
  useEffect(() => {
    const handleClickOutside = (event) => {
      if (showActionsMenu && !event.target.closest('.actions-dropdown')) {
        setShowActionsMenu(false);
      }
    };
    
    document.addEventListener('mousedown', handleClickOutside);
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [showActionsMenu]);
  
  // 计算下拉菜单位置
  useEffect(() => {
    if (showActionsMenu) {
      const dropdownElement = document.querySelector('.actions-dropdown');
      if (dropdownElement) {
        const rect = dropdownElement.getBoundingClientRect();
        setDropdownPosition({
          top: rect.bottom + 4,
          right: window.innerWidth - rect.right
        });
      }
    }
  }, [showActionsMenu]);

  // 计算分页数据
  const currentPagePresets = getCurrentPagePresets();
  const totalPages = getTotalPages();

  // 参数描述映射（全名用于悬浮提示）
  const parameterDescriptions = {
    temperature: "生成温度，控制随机性(0-2)",
    freq_penalty: "频率惩罚，降低重复token概率(-2到2)",
    pres_penalty: "存在惩罚，鼓励谈论新话题(-2到2)",
    top_p: "核采样，控制词汇选择范围(0-1)",
    top_k: "随机采样范围，从概率最高的K个词中选择",
    max_ctx: "上下文窗口大小(Token上限)",
    max_tokens: "单次回复的最大长度",
    request_timeout: "LLM请求超时时间（秒）",
    seed: "随机种子(-1为随机)",
    n: "生成回复的数量"
  };

  // 参数简写映射
  const parameterLabels = {
    temperature: "温度",
    freq_penalty: "频惩",
    pres_penalty: "存惩",
    top_p: "Top-P",
    top_k: "Top-K",
    max_ctx: "上下文",
    max_tokens: "MaxTok",
    request_timeout: "超时",
    seed: "种子",
    n: "数量"
  };

  // 显示工具提示
  const showTooltip = (event, content) => {
    setTooltip({
      visible: true,
      content,
      x: event.clientX,
      y: event.clientY
    });
  };

  // 隐藏工具提示
  const hideTooltip = () => {
    setTooltip({ ...tooltip, visible: false });
  };

  // 处理参数更新
  const handleParameterChange = (name, value) => {
    let convertedValue = value;
    if (name === 'temperature' || name === 'freq_penalty' || name === 'pres_penalty' || name === 'top_p') {
      convertedValue = parseFloat(value);
    } else if (name === 'top_k' || name === 'max_ctx' || name === 'max_tokens' || name === 'request_timeout' || name === 'seed' || name === 'n') {
      convertedValue = parseInt(value, 10);
    }

    // 将简写参数名转换回原始参数名
    const paramNameMap = {
      'freq_penalty': 'frequency_penalty',
      'pres_penalty': 'presence_penalty',
      'max_ctx': 'max_context'
    };
    
    const actualParamName = paramNameMap[name] || name;
    updateParameter({ name: actualParamName, value: convertedValue });
  };

  // 加载预设列表 - 由 SideBarLeft 标签切换时触发
  // 注意：fetchPresets 已在 SideBarLeft.jsx 的 handleTabClick 中调用

  // ✅ 处理页码跳转
  const handleJumpToPage = () => {
    if (!jumpPageInput) return;
    
    const pageNum = parseInt(jumpPageInput);
    
    // 验证页码范围
    if (isNaN(pageNum) || pageNum < 1 || pageNum > totalPages) {
      alert(`请输入 1 到 ${totalPages} 之间的页码`);
      setJumpPageInput('');
      return;
    }
    
    setCurrentPage(pageNum);
    setJumpPageInput('');
    fetchPresets();
  };

  // 创建空预设
  const handleCreateEmptyPreset = () => {
    setNewPresetName('');
    setShowSaveDialog(true);
  };

  // 保存当前预设（覆盖现有预设）
  const handleSaveCurrentPreset = async () => {
    if (!selectedPreset) {
      alert('请先选择一个预设');
      return;
    }
    
    try {
      // 构建预设数据 - 使用内部专有结构
      const presetData = {
        // GenerationPreset 部分 - 采样参数
        id: selectedPreset,
        name: presets.find(p => p.id === selectedPreset)?.name || selectedPreset,
        temperature: parameters.temperature,
        topP: parameters.top_p,
        topK: parameters.top_k,
        frequencyPenalty: parameters.frequency_penalty,
        presencePenalty: parameters.presence_penalty,
        maxLength: parameters.max_tokens,
        isDefault: false,
        
        // PromptPresetView 部分 - prompt组件列表
        characterId: 'global',
        entries: promptComponents.map((component, index) => ({
          identifier: component.identifier,
          name: component.name,
          enabled: component.enabled !== false,
          content: component.content || '',
          order: index,
          role: component.role === 0 ? 'system' : component.role === 1 ? 'user' : 'ai',
          tokenCount: component.content ? component.content.length : 0,
          isSystemNode: component.marker || false
        }))
      };

      // 发送到后端更新
      const response = await fetch(`/api/presets/${selectedPreset}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(presetData)
      });

      if (!response.ok) {
        throw new Error('Failed to update preset');
      }

      // ✅ 静默保存，不显示成功提示
    } catch (error) {
      console.error('保存预设失败:', error);
      alert('保存预设失败: ' + error.message);
    }
  };

  // 删除预设
  const handleDeletePreset = async (presetId) => {
    if (!confirm(`确定要删除预设 "${presets.find(p => p.id === presetId)?.name}" 吗？`)) {
      return;
    }
    
    try {
      const response = await fetch(`/api/presets/${presetId}`, {
        method: 'DELETE'
      });

      if (!response.ok) {
        throw new Error('Failed to delete preset');
      }

      // 如果删除的是当前选中的预设，清空选择
      if (selectedPreset === presetId) {
        setSelectedPreset('');
      }

      // 重新加载预设列表
      setCurrentPage(1);
      fetchPresets();
    } catch (error) {
      console.error('删除预设失败:', error);
      alert('删除预设失败: ' + error.message);
    }
  };

  // 保存当前设置为预设
  const handleSavePreset = async () => {
    if (newPresetName.trim()) {
      try {
        await saveCurrentAsPreset({ name: newPresetName });
        setNewPresetName('');
        setShowSaveDialog(false);
        // 重新加载预设列表并重置到第一页
        setCurrentPage(1);
        fetchPresets();
      } catch (error) {
        console.error('保存预设失败:', error);
        alert('保存预设失败: ' + error.message);
      }
    }
  };

  // 编辑预设名称
  const handleEditPreset = async () => {
    if (editPresetId && editPresetName.trim()) {
      try {
        // ✅ 使用专门的重命名 API
        const response = await fetch(`/api/presets/${editPresetId}/rename`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ newName: editPresetName })
        });

        if (!response.ok) {
          const errorData = await response.json();
          throw new Error(errorData.detail || 'Failed to rename preset');
        }

        const result = await response.json();
        
        setEditPresetId('');
        setEditPresetName('');
        setShowEditDialog(false);
        
        // ✅ 如果重命名后当前选中的预设 ID 变了，需要更新选中状态
        if (selectedPreset === editPresetId && result.newName) {
          setSelectedPreset(result.newName);
        }
        
        // 重新加载预设列表
        setCurrentPage(1);
        fetchPresets();
      } catch (error) {
        console.error('重命名预设失败:', error);
        alert('重命名预设失败: ' + error.message);
      }
    }
  };

  // 导入预设
  const handleImportPreset = async (file) => {
    console.log('\n' + '='.repeat(80));
    console.log('[预设导入] 📥 开始导入文件:', file.name);
    console.log('='.repeat(80));
    try {
      // 读取文件内容
      const importData = await new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = (e) => resolve(e.target.result);
        reader.onerror = (e) => reject(new Error('读取文件失败'));
        reader.readAsText(file);
      });
      
      const importedPreset = JSON.parse(importData);
      
      // 支持内部结构和SillyTavern结构
      let presetName = '';
      let importedParameters = {};
      let importedComponents = [];
      
      // 检测是否为内部结构（有 entries 字段）
      if (importedPreset.entries && Array.isArray(importedPreset.entries)) {
        // 内部结构
        presetName = importedPreset.name || file.name.replace('.json', '');
        console.log('[预设导入] ✅ 检测到内部格式');
        console.log('  - 预设名称:', presetName);
        importedParameters = {
          temperature: importedPreset.temperature,
          top_p: importedPreset.topP,
          top_k: importedPreset.topK,
          frequency_penalty: importedPreset.frequencyPenalty,
          presence_penalty: importedPreset.presencePenalty,
          max_tokens: importedPreset.maxLength,
          request_timeout: importedPreset.requestTimeout || 60
        };
        
        // 转换 entries 为 promptComponents 格式
        importedComponents = importedPreset.entries.map(entry => ({
          identifier: entry.identifier,
          name: entry.name,
          content: entry.content || '',
          enabled: entry.enabled !== false,
          role: entry.role === 'system' ? 0 : entry.role === 'user' ? 1 : 2,
          system_prompt: entry.role === 'system',
          marker: entry.isSystemNode || false
        })).sort((a, b) => {
          const orderA = importedPreset.entries.find(e => e.identifier === a.identifier)?.order || 0;
          const orderB = importedPreset.entries.find(e => e.identifier === b.identifier)?.order || 0;
          return orderA - orderB;
        });
      }
      // 兼容SillyTavern结构（有 prompts 或 parameters 字段）
      else if (importedPreset.name || importedPreset.temperature || importedPreset.parameters || importedPreset.prompts) {
        // SillyTavern 格式通常没有 name 字段，使用文件名
        presetName = importedPreset.name || file.name.replace('.json', '');
        console.log('[预设导入] ✅ 检测到 SillyTavern 格式');
        console.log('  - 预设名称:', presetName);
        
        // 提取参数
        importedParameters = importedPreset.parameters || {
          temperature: importedPreset.temperature,
          frequency_penalty: importedPreset.frequency_penalty,
          presence_penalty: importedPreset.presence_penalty,
          top_p: importedPreset.top_p,
          top_k: importedPreset.top_k,
          max_tokens: importedPreset.max_tokens || importedPreset.openai_max_tokens,
          request_timeout: importedPreset.request_timeout || 60
        };
        
        // 转换 SillyTavern 的 prompts 为内部格式
        if (importedPreset.prompts && Array.isArray(importedPreset.prompts)) {
          console.log('  - Prompts 数量:', importedPreset.prompts.length);
          
          // 获取 prompt_order（支持多个 prompt_order，优先使用最后一个或组件数最多的）
          let promptOrder = [];
          if (importedPreset.prompt_order && Array.isArray(importedPreset.prompt_order)) {
            // 策略：优先使用最后一个 prompt_order（通常是角色特定的，包含更多组件）
            // 如果只有一个，直接使用
            if (importedPreset.prompt_order.length === 1) {
              if (importedPreset.prompt_order[0].order) {
                promptOrder = importedPreset.prompt_order[0].order;
                console.log('  - 使用唯一的 prompt_order (组件数:', promptOrder.length, ')');
              }
            } else if (importedPreset.prompt_order.length > 1) {
              // 有多个时，使用最后一个（通常是最完整的）
              const lastOrder = importedPreset.prompt_order[importedPreset.prompt_order.length - 1];
              if (lastOrder && lastOrder.order) {
                promptOrder = lastOrder.order;
                console.log('  - 使用最后一个 prompt_order');
                console.log('    * character_id:', lastOrder.character_id);
                console.log('    * 组件数:', promptOrder.length);
              }
              
              console.log('  - 检测到', importedPreset.prompt_order.length, '个 prompt_order:');
              importedPreset.prompt_order.forEach((po, idx) => {
                console.log(`    [${idx}] character_id: ${po.character_id}, order_count: ${po.order?.length || 0}`);
              });
            }
          }
          
          // 创建 identifier 到 enabled 状态的映射
          const enabledMap = {};
          promptOrder.forEach(item => {
            if (item && item.identifier) {
              enabledMap[item.identifier] = item.enabled !== false;
            }
          });
          
          // 转换每个 prompt
          importedComponents = importedPreset.prompts.map((prompt, index) => {
            // 确定角色：system_prompt=true -> 0 (system), 否则根据 role 字段
            let role = 0; // 默认 system
            if (prompt.role !== undefined) {
              role = typeof prompt.role === 'string' 
                ? (prompt.role === 'system' ? 0 : prompt.role === 'user' ? 1 : 2)
                : prompt.role;
            } else if (prompt.system_prompt) {
              role = 0; // system
            } else {
              role = 1; // user
            }
            
            return {
              identifier: prompt.identifier || `prompt_${index}`,
              name: prompt.name || '未命名组件',
              content: prompt.content || '',
              enabled: enabledMap[prompt.identifier] !== undefined 
                ? enabledMap[prompt.identifier] 
                : (prompt.enabled !== false),
              role: role,
              system_prompt: role === 0,
              marker: prompt.marker || false
            };
          });
          
          // 如果有 prompt_order，按顺序排序
          if (promptOrder.length > 0) {
            const orderMap = {};
            promptOrder.forEach((item, idx) => {
              if (item && item.identifier) {
                orderMap[item.identifier] = idx;
              }
            });
            
            importedComponents.sort((a, b) => {
              const orderA = orderMap[a.identifier] !== undefined ? orderMap[a.identifier] : 999;
              const orderB = orderMap[b.identifier] !== undefined ? orderMap[b.identifier] : 999;
              return orderA - orderB;
            });
          }
          
          console.log('  - 转换后组件数量:', importedComponents.length);
        } else {
          console.log('  - ⚠️ 未找到 prompts 字段');
          importedComponents = [];
        }
      }
      
      if (presetName) {
        console.log('\n[预设导入] 🔄 应用导入的配置...');
        
        // ✅ 调试：检查导入的预设结构
        console.log('[预设导入] 🔍 检查预设文件结构...');
        console.log('[预设导入] 📋 预设文件名:', presetName);
        console.log('[预设导入] 🔑 是否有 extensions:', !!importedPreset.extensions);
        console.log('[预设导入] 📜 是否有 regex_scripts:', !!importedPreset.extensions?.regex_scripts);
        console.log('[预设导入] 📊 regex_scripts 数量:', importedPreset.extensions?.regex_scripts?.length || 0);
        
        // ✅ 提取并保存正则规则（如果存在）
        if (importedPreset.extensions?.regex_scripts && importedPreset.extensions.regex_scripts.length > 0) {
          const regexScripts = importedPreset.extensions.regex_scripts;
          console.log(`\n[预设导入] ✅ 检测到 ${regexScripts.length} 条正则规则`);
          console.log('[预设导入] 📜 前3条规则:', regexScripts.slice(0, 3).map(r => r.scriptName));
          
          try {
            // 将正则规则发送到后端保存
            console.log('[预设导入]  开始保存正则规则到后端...');
            const response = await fetch('/api/regex/import-from-preset', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({
                rules: regexScripts,
                scope: 'preset',
                presetName: presetName
              })
            });
            
            console.log('[预设导入] 📥 后端响应状态:', response.status);
            
            if (response.ok) {
              const result = await response.json();
              console.log('[预设导入] ✅ 正则规则已保存到:', `data/regex/presets/${presetName}.json`);
              console.log('[预设导入] 📊 导入结果:', result.message);
            } else {
              const errorText = await response.text();
              console.error('[预设导入] ❌ 保存正则规则失败:', response.status, errorText);
            }
          } catch (error) {
            console.error('[预设导入] ❌ 保存正则规则失败:', error);
          }
        } else {
          console.warn('[预设导入] ️ 预设中未找到 extensions.regex_scripts');
          console.log('[预设导入] 💡 预设文件中的 extensions 字段:', Object.keys(importedPreset.extensions || {}));
        }
        
        // 先更新参数
        console.log('  - 参数配置:', Object.keys(importedParameters).filter(k => importedParameters[k] !== undefined).join(', '));
        Object.keys(importedParameters).forEach(key => {
          if (importedParameters[key] !== undefined) {
            updateParameter({ name: key, value: importedParameters[key] });
          }
        });

        // 再更新组件列表
        if (importedComponents.length > 0) {
          console.log('  - 组件列表:', importedComponents.length, '个组件');
          setPromptComponents(importedComponents);
        }
        
        // 使用 requestAnimationFrame 确保状态更新完成后再保存
        requestAnimationFrame(() => {
          setTimeout(async () => {
            console.log('\n[预设导入] 💾 保存预设:', presetName);
            try {
              await saveCurrentAsPreset({ name: presetName });
              console.log('[预设导入] ✅ 预设保存成功');
              console.log('='.repeat(80) + '\n');
              
              // 重新加载预设列表并重置到第一页
              setCurrentPage(1);
              fetchPresets();
            } catch (error) {
              console.error('[预设导入] ❌ 保存预设失败:', error);
              console.log('='.repeat(80) + '\n');
              alert('保存预设失败: ' + error.message);
            }
          }, 50);
        });
      }
    } catch (error) {
      console.error('\n[预设导入] ❌ 导入失败:', error);
      console.log('='.repeat(80) + '\n');
      alert('导入预设失败: ' + error.message);
    }
  };

  // 导出预设 - 使用 SillyTavern 标准格式
  const handleExportPreset = () => {
    if (selectedPreset) {
      const preset = presets.find(p => p.id === selectedPreset);
      if (preset) {
        // 构建 SillyTavern 标准格式
        const exportData = {
          // 基本参数
          name: preset.name,
          temperature: parameters.temperature,
          frequency_penalty: parameters.frequency_penalty,
          presence_penalty: parameters.presence_penalty,
          top_p: parameters.top_p,
          top_k: parameters.top_k,
          max_tokens: parameters.max_tokens,
          request_timeout: parameters.request_timeout || 60,
          
          // SillyTavern 标准的 prompts 数组
          prompts: promptComponents.map((component) => ({
            identifier: component.identifier,
            name: component.name,
            content: component.content || '',
            system_prompt: component.role === 0,
            role: component.role === 0 ? 'system' : component.role === 1 ? 'user' : 'assistant',
            enabled: component.enabled !== false
          })),
          
          // prompt_order - SillyTavern 用于管理顺序和启用状态
          prompt_order: [{
            character_id: 'global',
            order: promptComponents.map(component => ({
              identifier: component.identifier,
              enabled: component.enabled !== false
            }))
          }]
        };
        
        const dataStr = JSON.stringify(exportData, null, 2);
        const dataBlob = new Blob([dataStr], { type: 'application/json' });
        const url = URL.createObjectURL(dataBlob);
        const link = document.createElement('a');
        link.href = url;
        link.download = `${preset.name}.json`;
        link.click();
        URL.revokeObjectURL(url);
      }
    }
  };

  // 添加新组件
  const handleAddNewComponent = () => {
    const newComponent = {
      identifier: `component_${Date.now()}`,
      name: '新组件',
      content: '',
      role: 0,
      system_prompt: false,
      marker: false,
      enabled: true
    };
    addComponent(newComponent);
  };

  // 开始编辑组件
  const handleStartEditComponent = (index) => {
    setEditingComponentIndex(index);
    setEditComponentName(promptComponents[index].name); // ✅ 初始化组件名称
    setEditComponentContent(promptComponents[index].content);
    setEditComponentRole(promptComponents[index].role || 0);
    setIsEditing(true);
    setShowComponentEditDialog(true);
  };

  // 查看/编辑组件内容 - 实时获取引用内容
  const handleViewComponent = (index) => {
    const component = promptComponents[index];
    
    // 如果是固定组件，实时从其他前端部件获取内容
    if (component.marker) {
      // TODO: 根据component.identifier从对应的Store中实时获取内容
      // 例如：chatHistory -> 从ChatBoxSlice获取当前聊天记录
      // charDescription -> 从CharacterSlice获取角色描述
      // 这里先显示提示信息
      setEditComponentContent(`[实时内容将从 ${component.name} 动态加载]\n\n当前暂不支持预览，该组件会在发送消息时自动从系统获取最新内容。`);
    } else {
      // 可编辑组件，显示保存的内容
      setEditComponentContent(component.content || '');
    }
    
    setEditingComponentIndex(index);
    setEditComponentName(component.name); // ✅ 初始化组件名称
    setEditComponentRole(component.role || 0);
    setIsEditing(!component.marker); // 固定组件不可编辑
    setShowComponentEditDialog(true);
  };

  // 保存组件编辑
  const handleSaveComponentEdit = async () => {
    if (editingComponentIndex >= 0 && isEditing) {
      // ✅ 先更新前端状态（包括名称和内容）
      updateComponent(editingComponentIndex, { 
        name: editComponentName,
        content: editComponentContent,
        role: editComponentRole
      });
      
      // ✅ 然后保存到后端
      if (selectedPreset) {
        try {
          // 构建预设数据
          const presetData = {
            name: selectedPreset,
            temperature: parameters.temperature,
            frequency_penalty: parameters.frequency_penalty,
            presence_penalty: parameters.presence_penalty,
            top_p: parameters.top_p,
            top_k: parameters.top_k,
            max_tokens: parameters.max_tokens,
            request_timeout: parameters.request_timeout || 60,
            
            prompts: promptComponents.map((component, idx) => ({
              identifier: component.identifier,
              name: idx === editingComponentIndex ? editComponentName : component.name,
              content: idx === editingComponentIndex ? editComponentContent : (component.content || ''),
              system_prompt: component.role === 0,
              role: idx === editingComponentIndex ? editComponentRole : component.role,
              enabled: component.enabled !== false
            })),
            
            prompt_order: [{
              character_id: 'global',
              order: promptComponents.map(component => ({
                identifier: component.identifier,
                enabled: component.enabled !== false
              }))
            }]
          };

          // 发送到后端更新
          const response = await fetch(`/api/presets/${selectedPreset}`, {
            method: 'PUT',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify(presetData)
          });

          if (!response.ok) {
            throw new Error('Failed to save preset');
          }
        } catch (error) {
          console.error('保存预设失败:', error);
          alert('保存预设失败: ' + error.message);
        }
      }
    }
    setEditingComponentIndex(-1);
    setEditComponentName('');
    setEditComponentContent('');
    setShowComponentEditDialog(false);
  };

  // 取消组件编辑
  const handleCancelComponentEdit = () => {
    setEditingComponentIndex(-1);
    setEditComponentName('');
    setEditComponentContent('');
    setShowComponentEditDialog(false);
  };

  // 关闭组件查看对话框
  const handleCloseComponentView = () => {
    setEditingComponentIndex(-1);
    setEditComponentName('');
    setEditComponentContent('');
    setShowComponentEditDialog(false);
  };

  // 切换组件启用状态
  const handleToggleComponentEnabled = (index) => {
    toggleComponentEnabled(index);
  };

  // 删除组件
  const handleDeleteComponent = (index) => {
    if (window.confirm('确定要删除这个组件吗？')) {
      removeComponent(index);
    }
  };

  // 拖拽开始
  const handleDragStart = (e, index) => {
    setDraggedItem(index);
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text/plain', index.toString());
    setTimeout(() => {
      e.target.classList.add('dragging');
    }, 0);
  };

  // 拖拽结束
  const handleDragEnd = (e) => {
    setDraggedItem(null);
    setDragOverItem(null);
    e.target.classList.remove('dragging');
  };

  // 拖拽经过
  const handleDragOver = (e, index) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    if (draggedItem === null || draggedItem === index) return;
    setDragOverItem(index);
  };

  // 放置
  const handleDrop = async (e, index) => {
    e.preventDefault();
    if (draggedItem === null || draggedItem === index) return;

    moveComponent(draggedItem, index);
    
    // ✅ 拖拽后保存排序到后端
    try {
      await saveComponentOrder();
    } catch (error) {
      console.error('Failed to save component order:', error);
      alert('保存排序失败: ' + error.message);
    }

    setDraggedItem(null);
    setDragOverItem(null);
  };

  return (
    <div className="preset-panel">
      {/* 工具提示 */}
      {tooltip.visible && (
        <div
          className="tooltip"
          style={{ left: `${tooltip.x}px`, top: `${tooltip.y}px` }}
        >
          {tooltip.content}
        </div>
      )}

      {/* 顶部：预设选择与操作 */}
      <div className="preset-header">
        {/* 预设选择下拉框 */}
        <div className="preset-select-wrapper">
          <select
            className="preset-select"
            value={selectedPreset}
            onChange={(e) => setSelectedPreset(e.target.value)}
            disabled={isLoadingPresets}
          >
            <option value="">{isLoadingPresets ? "加载中..." : "选择预设..."}</option>
            {currentPagePresets.map(preset => (
              <option key={preset.id} value={preset.id}>{preset.name}</option>
            ))}
          </select>
          
          {/* 操作下拉菜单 */}
          <div className="actions-dropdown">
            <button
              className="dropdown-toggle"
              onClick={() => setShowActionsMenu(!showActionsMenu)}
              onMouseEnter={(e) => showTooltip(e, "更多操作")}
              onMouseLeave={hideTooltip}
            >
              ⚙️
            </button>
            
            {showActionsMenu && (
              <div 
                className="dropdown-menu"
                style={{
                  top: `${dropdownPosition.top}px`,
                  right: `${dropdownPosition.right}px`
                }}
              >
                <button
                  className="dropdown-item"
                  title="创建一个全新的空白预设"
                  onClick={() => {
                    handleCreateEmptyPreset();
                    setShowActionsMenu(false);
                  }}
                >
                  ➕ 新建空预设
                </button>
                <button
                  className="dropdown-item"
                  disabled={!selectedPreset}
                  title="保存当前的参数和组件配置到当前预设"
                  onClick={() => {
                    if (selectedPreset) {
                      handleSaveCurrentPreset();
                    }
                    setShowActionsMenu(false);
                  }}
                >
                  💾 保存当前预设
                </button>
                <button
                  className="dropdown-item"
                  disabled={!selectedPreset}
                  title="重命名当前选中的预设"
                  onClick={() => {
                    if (selectedPreset) {
                      const preset = presets.find(p => p.id === selectedPreset);
                      setEditPresetId(selectedPreset);
                      setEditPresetName(preset?.name || '');
                      setShowEditDialog(true);
                    }
                    setShowActionsMenu(false);
                  }}
                >
                  ✏️ 重命名
                </button>
                <button
                  className="dropdown-item"
                  title="从 JSON 文件导入预设配置"
                  onClick={() => {
                    console.log('[Preset Import] 点击导入按钮');
                    // 创建文件选择器
                    const input = document.createElement('input');
                    input.type = 'file';
                    input.accept = '.json';
                    input.onchange = async (e) => {
                      console.log('[Preset Import] 文件选择器触发');
                      const file = e.target.files[0];
                      if (!file) {
                        console.log('[Preset Import] 未选择文件');
                        return;
                      }
                      console.log('[Preset Import] 选择的文件:', file.name);
                      
                      try {
                        await handleImportPreset(file);
                        console.log('[Preset Import] 导入完成');
                        setShowActionsMenu(false);
                      } catch (error) {
                        console.error('[Preset Import] 导入失败:', error);
                        alert('导入预设失败: ' + error.message);
                      }
                    };
                    input.click();
                  }}
                >
                  📥 导入
                </button>
                <button
                  className="dropdown-item"
                  disabled={!selectedPreset}
                  title="将当前预设导出为 JSON 文件"
                  onClick={() => {
                    handleExportPreset();
                    setShowActionsMenu(false);
                  }}
                >
                  📤 导出
                </button>
                <button
                  className="dropdown-item delete-item"
                  disabled={!selectedPreset}
                  title="删除当前选中的预设"
                  onClick={() => {
                    if (selectedPreset) {
                      handleDeletePreset(selectedPreset);
                    }
                    setShowActionsMenu(false);
                  }}
                >
                  🗑️ 删除
                </button>
              </div>
            )}
          </div>
        </div>
      </div>

      {/* 保存预设对话框 */}
      {showSaveDialog && (
        <div className="preset-save-dialog">
          <input
            type="text"
            value={newPresetName}
            onChange={(e) => setNewPresetName(e.target.value)}
            placeholder="预设名称"
          />
          <div className="dialog-buttons">
            <button onClick={handleSavePreset}>保存</button>
            <button onClick={() => setShowSaveDialog(false)}>取消</button>
          </div>
        </div>
      )}

      {/* 编辑预设对话框 */}
      {showEditDialog && (
        <div className="preset-edit-dialog">
          <input
            type="text"
            value={editPresetName}
            onChange={(e) => setEditPresetName(e.target.value)}
            placeholder="预设名称"
          />
          <div className="dialog-buttons">
            <button onClick={handleEditPreset}>保存</button>
            <button onClick={() => setShowEditDialog(false)}>取消</button>
          </div>
        </div>
      )}


      {/* 编辑/查看组件内容对话框 */}
      {showComponentEditDialog && (
        <div className="component-edit-dialog">
          <div className="dialog-header">
            <h3>{isEditing ? '编辑' : '查看'}组件: {editingComponentIndex >= 0 && promptComponents[editingComponentIndex].name}</h3>
            <button className="close-btn" onClick={handleCloseComponentView}>×</button>
          </div>
          <div className="dialog-content">
            {/* ✅ 检查是否是固有组件（marker=true） */}
            {editingComponentIndex >= 0 && promptComponents[editingComponentIndex].marker && (
              <div className="builtin-component-notice">
                <p>⚠️ 这是 SillyTavern 的固有组件，不可编辑。</p>
                <p>📌 <strong>数据来源：</strong>{promptComponents[editingComponentIndex].dataSource || '系统自动获取'}</p>
                <p>💡 该组件会在发送消息时从对应的数据源自动提取最新内容。</p>
              </div>
            )}
            
            {/* ✅ 组件名称输入框 - 固有组件禁用 */}
            {isEditing && !promptComponents[editingComponentIndex]?.marker && (
              <div className="component-name-input">
                <label className="name-label">组件名称：</label>
                <input
                  type="text"
                  className="name-input"
                  value={editComponentName}
                  onChange={(e) => setEditComponentName(e.target.value)}
                  placeholder="输入组件名称"
                />
              </div>
            )}
            
            {/* ✅ 角色选择器 - 固有组件禁用 */}
            {isEditing && !promptComponents[editingComponentIndex]?.marker && (
              <div className="component-role-selector">
                <label className="role-label">角色：</label>
                <select
                  className="role-select"
                  value={editComponentRole}
                  onChange={(e) => setEditComponentRole(Number(e.target.value))}
                >
                  <option value={0}>System (系统)</option>
                  <option value={1}>User (用户)</option>
                  <option value={2}>AI (助手)</option>
                </select>
              </div>
            )}
            
            {/* ✅ 内容文本域 - 固有组件只读 */}
            <textarea
              value={editComponentContent}
              onChange={(e) => setEditComponentContent(e.target.value)}
              className="component-textarea"
              readOnly={!isEditing || promptComponents[editingComponentIndex]?.marker}
              rows={20}
            />
          </div>
          <div className="dialog-footer">
            <span className="token-count">
              {editComponentContent ? editComponentContent.length : 0}
            </span>
            {isEditing && !promptComponents[editingComponentIndex]?.marker && (
              <div className="dialog-buttons">
                <button onClick={handleSaveComponentEdit}>保存</button>
                <button onClick={handleCancelComponentEdit}>取消</button>
              </div>
            )}
          </div>
        </div>
      )}

      {/* 参数设置区域 */}
      <div className="preset-parameters-container">
        <div
          className="parameters-header"
          onClick={toggleParametersExpanded}
        >
          <span>参数设置</span>
          {/* 生成数量 - 放在标题栏旁边 */}
          <div className="header-parameter">
            <label
              className="header-param-label"
              onMouseEnter={(e) => showTooltip(e, parameterDescriptions.n)}
              onMouseLeave={hideTooltip}
            >
              {parameterLabels.n}
            </label>
            <input
              type="number"
              min="1"
              value={parameters.n}
              onChange={(e) => handleParameterChange('n', e.target.value)}
              className="header-param-input"
              onClick={(e) => e.stopPropagation()} // 防止点击输入框时折叠
            />
          </div>
          <span className={`expand-icon ${isParametersExpanded ? 'expanded' : ''}`}>▼</span>
        </div>

        {isParametersExpanded && (
          <div className="preset-parameters">
            {/* 温度输入框 */}
            <div className="parameter-row-compact">
              <label
                className="parameter-label-compact"
                onMouseEnter={(e) => showTooltip(e, parameterDescriptions.temperature)}
                onMouseLeave={hideTooltip}
              >
                {parameterLabels.temperature}
              </label>
              <input
                type="number"
                min="0"
                max="2"
                step="0.1"
                value={parameters.temperature}
                onChange={(e) => handleParameterChange('temperature', e.target.value)}
                className="parameter-input-compact"
              />
            </div>

            {/* 频率惩罚输入框 */}
            <div className="parameter-row-compact">
              <label
                className="parameter-label-compact"
                onMouseEnter={(e) => showTooltip(e, parameterDescriptions.freq_penalty)}
                onMouseLeave={hideTooltip}
              >
                {parameterLabels.freq_penalty}
              </label>
              <input
                type="number"
                min="-2"
                max="2"
                step="0.1"
                value={parameters.frequency_penalty}
                onChange={(e) => handleParameterChange('freq_penalty', e.target.value)}
                className="parameter-input-compact"
              />
            </div>

            {/* 存在惩罚输入框 */}
            <div className="parameter-row-compact">
              <label
                className="parameter-label-compact"
                onMouseEnter={(e) => showTooltip(e, parameterDescriptions.pres_penalty)}
                onMouseLeave={hideTooltip}
              >
                {parameterLabels.pres_penalty}
              </label>
              <input
                type="number"
                min="-2"
                max="2"
                step="0.1"
                value={parameters.presence_penalty}
                onChange={(e) => handleParameterChange('pres_penalty', e.target.value)}
                className="parameter-input-compact"
              />
            </div>

            {/* Top P 输入框 */}
            <div className="parameter-row-compact">
              <label
                className="parameter-label-compact"
                onMouseEnter={(e) => showTooltip(e, parameterDescriptions.top_p)}
                onMouseLeave={hideTooltip}
              >
                {parameterLabels.top_p}
              </label>
              <input
                type="number"
                min="0"
                max="1"
                step="0.05"
                value={parameters.top_p}
                onChange={(e) => handleParameterChange('top_p', e.target.value)}
                className="parameter-input-compact"
              />
            </div>

            {/* Top K 输入框 */}
            <div className="parameter-row-compact">
              <label
                className="parameter-label-compact"
                onMouseEnter={(e) => showTooltip(e, parameterDescriptions.top_k)}
                onMouseLeave={hideTooltip}
              >
                {parameterLabels.top_k}
              </label>
              <input
                type="number"
                min="0"
                value={parameters.top_k}
                onChange={(e) => handleParameterChange('top_k', e.target.value)}
                className="parameter-input-compact"
              />
            </div>

            {/* 最大上下文输入框 */}
            <div className="parameter-row-compact">
              <label
                className="parameter-label-compact"
                onMouseEnter={(e) => showTooltip(e, parameterDescriptions.max_ctx)}
                onMouseLeave={hideTooltip}
              >
                {parameterLabels.max_ctx}
              </label>
              <input
                type="number"
                min="1"
                max="10000000"
                value={parameters.max_context}
                onChange={(e) => handleParameterChange('max_ctx', e.target.value)}
                className="parameter-input-compact"
              />
            </div>

            {/* 最大Token输入框 */}
            <div className="parameter-row-compact">
              <label
                className="parameter-label-compact"
                onMouseEnter={(e) => showTooltip(e, parameterDescriptions.max_tokens)}
                onMouseLeave={hideTooltip}
              >
                {parameterLabels.max_tokens}
              </label>
              <input
                type="number"
                min="1"
                max="100000"
                value={parameters.max_tokens}
                onChange={(e) => handleParameterChange('max_tokens', e.target.value)}
                className="parameter-input-compact"
              />
            </div>

            {/* 请求超时输入框 */}
            <div className="parameter-row-compact">
              <label
                className="parameter-label-compact"
                onMouseEnter={(e) => showTooltip(e, parameterDescriptions.request_timeout)}
                onMouseLeave={hideTooltip}
              >
                {parameterLabels.request_timeout}
              </label>
              <input
                type="number"
                min="5"
                max="600"
                value={parameters.request_timeout || 60}
                onChange={(e) => handleParameterChange('request_timeout', e.target.value)}
                className="parameter-input-compact"
              />
            </div>

            {/* 随机种子输入框 */}
            <div className="parameter-row-compact">
              <label
                className="parameter-label-compact"
                onMouseEnter={(e) => showTooltip(e, parameterDescriptions.seed)}
                onMouseLeave={hideTooltip}
              >
                {parameterLabels.seed}
              </label>
              <input
                type="number"
                value={parameters.seed}
                onChange={(e) => handleParameterChange('seed', e.target.value)}
                className="parameter-input-compact"
              />
            </div>
          </div>
        )}
      </div>

      {/* 预设组件列表 */}
      <div className="preset-components-section">
        <div className="components-header">
          <h3>预设组件</h3>
          <button
            onClick={handleAddNewComponent}
            className="add-component-btn"
            onMouseEnter={(e) => showTooltip(e, "添加新组件")}
            onMouseLeave={hideTooltip}
          >
            + 添加组件
          </button>
        </div>

        <div className="components-list draggable-container">
          {promptComponents.map((component, index) => (
            <React.Fragment key={component.identifier}>
              {/* 拖拽指示器 - 在组件上方 */}
              <div
                className={`drag-indicator ${dragOverItem === index ? 'visible' : ''}`}
                onDragOver={(e) => handleDragOver(e, index)}
                onDrop={(e) => handleDrop(e, index)}
              />

              {/* 组件项 */}
              <div
                className={`prompt-component-item ${!component.enabled ? 'disabled' : ''} ${component.marker ? 'marker' : ''} ${draggedItem === index ? 'dragging' : ''}`}
                draggable={!component.marker}
                onDragStart={(e) => handleDragStart(e, index)}
                onDragEnd={handleDragEnd}
                onDragOver={(e) => handleDragOver(e, index)}
                onDrop={(e) => handleDrop(e, index)}
              >
                <div className="component-header">
                  <div className="component-controls">
                    <div className="drag-handle">⋮⋮</div>
                    <button
                      className={`toggle-btn ${component.enabled ? 'enabled' : 'disabled'}`}
                      onClick={() => handleToggleComponentEnabled(index)}
                      onMouseEnter={(e) => showTooltip(e, component.enabled ? "禁用组件" : "启用组件")}
                      onMouseLeave={hideTooltip}
                    >
                      {component.enabled ? '✓' : '○'}
                    </button>
                    <span className="component-name">{component.name}</span>
                    {component.marker && (
                      <span className="component-marker-badge">🔒</span>
                    )}
                  </div>
                  <div className="component-actions">
                    <button
                      className="edit-btn"
                      onClick={() => handleStartEditComponent(index)}
                      onMouseEnter={(e) => showTooltip(e, "编辑/查看组件")}
                      onMouseLeave={hideTooltip}
                    >
                      ✏️
                    </button>
                    <span className="token-count">
                      {component.content ? component.content.length : 0}
                    </span>
                    {!component.marker && (
                      <button
                        className="delete-btn"
                        onClick={() => handleDeleteComponent(index)}
                        onMouseEnter={(e) => showTooltip(e, "删除组件")}
                        onMouseLeave={hideTooltip}
                      >
                        🗑️
                      </button>
                    )}
                  </div>
                </div>
              </div>
            </React.Fragment>
          ))}

          {/* 最后一个拖拽指示器 - 在列表末尾 */}
          <div
            className={`drag-indicator ${dragOverItem === promptComponents.length ? 'visible' : ''}`}
            onDragOver={(e) => {
              e.preventDefault();
              handleDragOver(e, promptComponents.length);
            }}
            onDrop={(e) => handleDrop(e, promptComponents.length)}
          />
        </div>

        {/* 分页控件 */}
        {totalPages > 1 && (
          <div className="pagination-controls">
            <button 
              className="pagination-btn"
              onClick={() => {
                setCurrentPage(Math.max(1, currentPage - 1));
                fetchPresets();
              }}
              disabled={currentPage === 1}
            >
              上一页
            </button>
            
            {/* ✅ 页码跳转输入框 */}
            <div className="page-jump-container">
              <input
                type="number"
                className="page-jump-input"
                value={jumpPageInput}
                onChange={(e) => setJumpPageInput(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') {
                    handleJumpToPage();
                  }
                }}
                placeholder="页码"
                min="1"
                max={totalPages}
              />
              <button
                className="pagination-btn btn-jump"
                onClick={handleJumpToPage}
                disabled={!jumpPageInput}
              >
                跳转
              </button>
            </div>
            
            <span className="pagination-info">
              第 {currentPage} / {totalPages} 页
            </span>
            
            <button 
              className="pagination-btn"
              onClick={() => {
                setCurrentPage(Math.min(totalPages, currentPage + 1));
                fetchPresets();
              }}
              disabled={currentPage === totalPages}
            >
              下一页
            </button>
            
            <select 
              className="page-size-selector"
              value={pageSize}
              onChange={(e) => {
                setPageSize(Number(e.target.value));
                fetchPresets();
              }}
            >
              <option value={8}>8条/页</option>
              <option value={12}>12条/页</option>
              <option value={20}>20条/页</option>
              <option value={50}>50条/页</option>
            </select>
          </div>
        )}

      </div>
    </div>
  );
};

export default PresetPanel;
