import React, { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { api, getCurrentAccountId, setCurrentAccountId } from '../services/api'
import './ConfigPanel.css'

const ConfigPanel = ({ currentUser }) => {
  const [configs, setConfigs] = useState({})
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [message, setMessage] = useState('')
  const [feasibilityCheck, setFeasibilityCheck] = useState(null)
  const [checkingFeasibility, setCheckingFeasibility] = useState(false)
  const [systemStatus, setSystemStatus] = useState(null)
  const [backendStatus, setBackendStatus] = useState(null)
  const [systemBusy, setSystemBusy] = useState(false)
  const [accountTradingStatus, setAccountTradingStatus] = useState(null)
  const [accountTradingErr, setAccountTradingErr] = useState('')
  const [currentAccountMeta, setCurrentAccountMeta] = useState(null)
  const [configMeta, setConfigMeta] = useState(null)

  // 多账号：当前账号（仅用于配置页提示；全局切换器在顶部导航）
  const [accountId, setAccountId] = useState(getCurrentAccountId())

  const isAdmin = (currentUser?.role || '') === 'admin'
  const globalStrategyAccountId = parseInt(String(configMeta?.global_strategy_account_id || '1'), 10) || 1
  const isGlobalStrategyAccount = isAdmin && accountId === globalStrategyAccountId
  const loadConfigMeta = async () => {
    try {
      const m = await api.getConfigMeta()
      setConfigMeta(m || null)
    } catch (e) {
      setConfigMeta(null)
    }
  }

  // 账号管理（超管）
  const [accountsAdmin, setAccountsAdmin] = useState([])
  const [accountsBusy, setAccountsBusy] = useState(false)
  const [showAccountsAdmin, setShowAccountsAdmin] = useState(false)
  const [newAccount, setNewAccount] = useState({
    name: '',
    api_key: '',
    api_secret: '',
    use_testnet: false,
    status: 'active',
  })
  const [credEditId, setCredEditId] = useState(null)
  const [credForm, setCredForm] = useState({ api_key: '', api_secret: '', use_testnet: false })

  // “PCT”类配置里有少数是“百分比数值（<=1表示<=1%）”，而不是“0~1比例”
  // 例如 LIMIT_ORDER_OFFSET_PCT=0.5 表示 0.5%（而不是 50%）
  const PCT_LIKE_KEYS = new Set([
    'LIMIT_ORDER_OFFSET_PCT',
    'ENTRY_MAX_DRIFT_PCT_TRENDING',
    'ENTRY_MAX_DRIFT_PCT_RANGING',
  ])

  // 配置快照（用于整体分析/导出）
  const [showSnapshot, setShowSnapshot] = useState(false)
  const [snapshotText, setSnapshotText] = useState('')
  const [snapshotIncludeSecrets, setSnapshotIncludeSecrets] = useState(false)
  const [snapshotBusy, setSnapshotBusy] = useState(false)

  // 预设方案配置
  // 注意：百分比配置使用整数形式（如8.0表示8%），在应用时会转换为小数（0.08）
  const presets = {
    swing: {
      name: '波段回归（推荐）',
      desc: '根治高频与追价：关闭智能入场，回归“纯限价 + 30分钟扫描 + 更高信号门槛”的低频波段。建议先跑20-30单再评估。',
      configs: {
        // 操作频率
        SCAN_INTERVAL: 1800, // 30分钟
        TOP_N_SYMBOLS: 8,

        // 仓位管理（重要语义：这些百分比均按“保证金占用比例”理解）
        MAX_POSITION_PERCENT: 2.0, // 2%
        MAX_TOTAL_POSITION_PERCENT: 20.0, // 20%
        MIN_POSITION_PERCENT: 0.0, // 0%（等价于关闭最小仓位占比）

        // 风控
        MIN_SIGNAL_STRENGTH: 8,
        USE_TRAILING_STOP: false,  // 禁用移动止损，让利润奔跑
        ATR_TAKE_PROFIT_MULTIPLIER: 4.5,  // 放大ATR止盈倍数（从3.0提升到4.5）
        TAKE_PROFIT_PERCENT: 25.0,  // 放宽固定止盈（从30%到25%，配合ATR止盈放大盈亏比）
        MIN_HOLD_TIME_SEC: 1800,  // 最小持仓时间30分钟（强制波段持仓纪律）

        // 根治：关闭智能入场（回归纯限价，不追价/不市价兜底）
        SMART_ENTRY_ENABLED: false,
      },
    },
    fill: {
      name: '成交优先（更少漏单）',
      desc: '优先解决“挂单NEW→超时撤单→没成交”的问题：解锁自动交易过滤 + 保守智能入场（限制追价步数与追价上限），在趋势强时允许可控的市价兜底。',
      configs: {
        // 频率与精选
        SCAN_INTERVAL: 1800,
        TOP_N_SYMBOLS: 6,
        MIN_SIGNAL_STRENGTH: 7,

        // 自动交易过滤：先保证“会下单”
        AUTO_TRADE_ONLY_TRENDING: false,
        AUTO_TRADE_ALLOW_4H_NEUTRAL: true,

        // 入场（减少撤单/漏单）
        SMART_ENTRY_ENABLED: true,
        LIMIT_ORDER_OFFSET_PCT: 0.1, // 0.1% 更贴近当前价
        ENTRY_CONFIRM_TIMEOUT_SEC: 120,
        ENTRY_CHASE_MAX_STEPS: 2,
        ENTRY_STEP_WAIT_SEC: 20,
        ENTRY_MARKET_FALLBACK_AFTER_SEC: 60,
        ENTRY_MAX_DRIFT_PCT_TRENDING: 0.3, // 0.3%
        ENTRY_MAX_DRIFT_PCT_RANGING: 0.15, // 0.15%

        // 风控：默认关闭移动止损（避免“保本价”过早触发）
        USE_TRAILING_STOP: false,  // 禁用移动止损，让利润奔跑
        ATR_TAKE_PROFIT_MULTIPLIER: 4.5,  // 放大ATR止盈倍数（从3.0提升到4.5）
        TAKE_PROFIT_PERCENT: 25.0,  // 放宽固定止盈（从30%到25%，配合ATR止盈放大盈亏比）
        MIN_HOLD_TIME_SEC: 1800,  // 最小持仓时间30分钟（强制波段持仓纪律）
      },
    },
    strict: {
      name: '精选低频（高胜率倾向）',
      desc: '更偏“少单、质量优先”：仅趋势行情自动交易 + 4H中性不自动下单 + 更高信号门槛。仍保持较贴近的限价偏移，减少“完全成交不了”。',
      configs: {
        SCAN_INTERVAL: 1800,
        TOP_N_SYMBOLS: 6,
        MIN_SIGNAL_STRENGTH: 8,

        AUTO_TRADE_ONLY_TRENDING: true,
        AUTO_TRADE_ALLOW_4H_NEUTRAL: false,

        SMART_ENTRY_ENABLED: false,
        LIMIT_ORDER_OFFSET_PCT: 0.1,
        ENTRY_CONFIRM_TIMEOUT_SEC: 180,

        USE_TRAILING_STOP: false,  // 禁用移动止损，让利润奔跑
        ATR_TAKE_PROFIT_MULTIPLIER: 4.5,  // 放大ATR止盈倍数（从3.0提升到4.5）
        TAKE_PROFIT_PERCENT: 25.0,  // 放宽固定止盈（从30%到25%，配合ATR止盈放大盈亏比）
        MIN_HOLD_TIME_SEC: 1800,  // 最小持仓时间30分钟（强制波段持仓纪律）
      },
    },
    steady: {
      name: '稳定出单（均衡收益/频率）',
      desc: '在“会下单”的基础上略提高出单频率：更短扫描间隔 + 更宽松门槛 + 保守智能入场（追价受限），适合想要稳定有单但不想回到高频。',
      configs: {
        SCAN_INTERVAL: 900,
        TOP_N_SYMBOLS: 8,
        MIN_SIGNAL_STRENGTH: 6,

        AUTO_TRADE_ONLY_TRENDING: false,
        AUTO_TRADE_ALLOW_4H_NEUTRAL: true,

        SMART_ENTRY_ENABLED: true,
        LIMIT_ORDER_OFFSET_PCT: 0.12,
        ENTRY_CONFIRM_TIMEOUT_SEC: 120,
        ENTRY_CHASE_MAX_STEPS: 3,
        ENTRY_STEP_WAIT_SEC: 15,
        ENTRY_MARKET_FALLBACK_AFTER_SEC: 45,
        ENTRY_MAX_DRIFT_PCT_TRENDING: 0.4,
        ENTRY_MAX_DRIFT_PCT_RANGING: 0.2,

        USE_TRAILING_STOP: false,  // 禁用移动止损，让利润奔跑
        ATR_TAKE_PROFIT_MULTIPLIER: 4.5,  // 放大ATR止盈倍数（从3.0提升到4.5）
        TAKE_PROFIT_PERCENT: 25.0,  // 放宽固定止盈（从30%到25%，配合ATR止盈放大盈亏比）
        MIN_HOLD_TIME_SEC: 1800,  // 最小持仓时间30分钟（强制波段持仓纪律）
      },
    },
    conservative: {
      name: '保守配置',
      desc: '适合新手，风险较低，止损止盈较宽松，避免被正常波动触发',
      configs: {
        SCAN_INTERVAL: 900,
        MIN_CHANGE_PERCENT: 2.0,  // 2%
        MIN_SIGNAL_STRENGTH: 5,
        TOP_N_SYMBOLS: 10,
        MAX_SCAN_SYMBOLS: 150,
        MIN_VOLATILITY: 0.02,  // 保持小数形式（波动率）
        STOP_LOSS_PERCENT: 10.0,  // 10%（相对于保证金，更宽松）
        TAKE_PROFIT_PERCENT: 25.0,  // 25%（相对于保证金，从20%提升到25%，放大盈亏比）
        MIN_STOP_LOSS_PRICE_PCT: 2.0,  // 2%最小价格变动保护
        MIN_TAKE_PROFIT_PRICE_PCT: 3.0,  // 3%最小价格变动保护
        USE_TRAILING_STOP: false,  // 禁用移动止损，让利润奔跑
        ATR_TAKE_PROFIT_MULTIPLIER: 4.5,  // 放大ATR止盈倍数（从3.0提升到4.5）
        MIN_HOLD_TIME_SEC: 1800  // 最小持仓时间30分钟（强制波段持仓纪律）
      }
    },
    balanced: {
      name: '平衡配置',
      desc: '推荐使用，平衡频率和质量，止损止盈适中（盈亏比2.5:1）',
      configs: {
        SCAN_INTERVAL: 600,
        MIN_CHANGE_PERCENT: 1.5,  // 1.5%
        MIN_SIGNAL_STRENGTH: 4,
        TOP_N_SYMBOLS: 12,
        MAX_SCAN_SYMBOLS: 250,
        MIN_VOLATILITY: 0.018,  // 保持小数形式（波动率）
        STOP_LOSS_PERCENT: 8.0,  // 8%（相对于保证金，默认值）
        TAKE_PROFIT_PERCENT: 25.0,  // 25%（相对于保证金，从20%提升到25%，放大盈亏比）
        MIN_STOP_LOSS_PRICE_PCT: 2.0,  // 2%最小价格变动保护
        MIN_TAKE_PROFIT_PRICE_PCT: 3.0,  // 3%最小价格变动保护
        USE_TRAILING_STOP: false,  // 禁用移动止损，让利润奔跑
        ATR_TAKE_PROFIT_MULTIPLIER: 4.5,  // 放大ATR止盈倍数（从3.0提升到4.5）
        MIN_HOLD_TIME_SEC: 1800  // 最小持仓时间30分钟（强制波段持仓纪律）
      }
    },
    aggressive: {
      name: '激进高频',
      desc: '晚间波动大时使用，交易频率高，止损较紧但止盈合理（盈亏比3:1）',
      configs: {
        SCAN_INTERVAL: 300,
        MIN_CHANGE_PERCENT: 1.0,  // 1%
        MIN_SIGNAL_STRENGTH: 3,
        TOP_N_SYMBOLS: 18,
        MAX_SCAN_SYMBOLS: 350,
        MIN_VOLATILITY: 0.015,  // 保持小数形式（波动率）
        STOP_LOSS_PERCENT: 5.0,  // 5%（相对于保证金，较紧）
        TAKE_PROFIT_PERCENT: 25.0,  // 25%（相对于保证金，从15%大幅提升到25%，放大盈亏比到5:1）
        MIN_STOP_LOSS_PRICE_PCT: 1.5,  // 1.5%最小价格变动保护
        MIN_TAKE_PROFIT_PRICE_PCT: 2.0,  // 2%最小价格变动保护
        USE_TRAILING_STOP: false,  // 禁用移动止损，让利润奔跑
        ATR_TAKE_PROFIT_MULTIPLIER: 4.5,  // 放大ATR止盈倍数（从3.0提升到4.5）
        MIN_HOLD_TIME_SEC: 1800  // 最小持仓时间30分钟（强制波段持仓纪律）
      }
    }
  }

  const loadSystemStatus = async () => {
    try {
      const res = await api.getTradingSystemStatus()
      setSystemStatus(res)
    } catch (error) {
      // 静默失败：不影响配置页使用
    }
  }

  const loadBackendStatus = async () => {
    try {
      const res = await api.getBackendStatus()
      setBackendStatus(res)
    } catch (error) {
      // 静默失败：不影响配置页使用
    }
  }

  const loadAccountTradingStatus = async () => {
    try {
      const res = await api.getAccountTradingStatus(accountId)
      setAccountTradingStatus(res)
      setAccountTradingErr('')
    } catch (error) {
      setAccountTradingStatus(null)
      setAccountTradingErr(error?.message || '获取交易进程状态失败')
    }
  }

  const loadCurrentAccountMeta = async () => {
    try {
      const list = await api.getAccounts()
      const accounts = Array.isArray(list) ? list : []
      const meta = accounts.find((a) => parseInt(String(a?.id || '0'), 10) === parseInt(String(accountId || '0'), 10))
      setCurrentAccountMeta(meta || null)
      // 同步 testnet 开关到表单（仅在未输入时同步，避免打断正在输入）
      if (meta && !credForm.api_key && !credForm.api_secret) {
        setCredForm((prev) => ({ ...prev, use_testnet: !!meta.use_testnet }))
      }
    } catch (e) {
      setCurrentAccountMeta(null)
    }
  }

  const handleAccountTradingEnsure = async () => {
    setSystemBusy(true)
    setMessage('')
    try {
      const res = await api.ensureAccountTradingProgram(accountId)
      setMessage(`已生成/刷新 supervisor 配置：${res.program || ''}`)
      await loadAccountTradingStatus()
    } catch (error) {
      setMessage('生成 supervisor 配置失败: ' + (error.message || '未知错误'))
    } finally {
      setSystemBusy(false)
    }
  }

  const handleAccountTradingStart = async () => {
    const hasKey = !!currentAccountMeta?.has_api_key
    const hasSecret = !!currentAccountMeta?.has_api_secret
    if (!hasKey || !hasSecret) {
      setMessage('请先在“账号密钥（当前账号）”中配置 BINANCE_API_KEY 与 BINANCE_API_SECRET，然后再启动交易进程')
      return
    }
    setSystemBusy(true)
    setMessage('')
    try {
      const res = await api.startAccountTrading(accountId)
      setMessage(res.message || '交易进程已启动')
      await loadAccountTradingStatus()
    } catch (error) {
      setMessage('启动交易进程失败: ' + (error.message || '未知错误'))
    } finally {
      setSystemBusy(false)
    }
  }

  const handleAccountTradingStop = async () => {
    setSystemBusy(true)
    setMessage('')
    try {
      const res = await api.stopAccountTrading(accountId)
      setMessage(res.message || '交易进程已停止')
      await loadAccountTradingStatus()
    } catch (error) {
      setMessage('停止交易进程失败: ' + (error.message || '未知错误'))
    } finally {
      setSystemBusy(false)
    }
  }

  const handleAccountTradingRestart = async () => {
    const hasKey = !!currentAccountMeta?.has_api_key
    const hasSecret = !!currentAccountMeta?.has_api_secret
    if (!hasKey || !hasSecret) {
      setMessage('请先在“账号密钥（当前账号）”中配置 BINANCE_API_KEY 与 BINANCE_API_SECRET，然后再重启交易进程')
      return
    }
    setSystemBusy(true)
    setMessage('')
    try {
      const res = await api.restartAccountTrading(accountId)
      setMessage(res.message || '交易进程已重启')
      await loadAccountTradingStatus()
    } catch (error) {
      setMessage('重启交易进程失败: ' + (error.message || '未知错误'))
    } finally {
      setSystemBusy(false)
    }
  }

  const handleClearCache = async () => {
    setSystemBusy(true)
    setMessage('')
    try {
      const res = await api.clearSystemCache()
      setMessage(res.message || '缓存已清理')
      await loadConfigs()
      await loadSystemStatus()
    } catch (error) {
      setMessage('清理缓存失败: ' + (error.message || '未知错误'))
    } finally {
      setSystemBusy(false)
    }
  }

  const handleStartTrading = async () => {
    setSystemBusy(true)
    setMessage('')
    try {
      const res = await api.startTradingSystem()
      setMessage(res.message || '交易系统已启动')
      await loadSystemStatus()
    } catch (error) {
      setMessage('启动失败: ' + (error.message || '未知错误'))
    } finally {
      setSystemBusy(false)
    }
  }

  const handleStopTrading = async () => {
    setSystemBusy(true)
    setMessage('')
    try {
      const res = await api.stopTradingSystem()
      setMessage(res.message || '交易系统已停止')
      await loadSystemStatus()
    } catch (error) {
      setMessage('停止失败: ' + (error.message || '未知错误'))
    } finally {
      setSystemBusy(false)
    }
  }

  const handleRestartTrading = async () => {
    setSystemBusy(true)
    setMessage('')
    try {
      const res = await api.restartTradingSystem()
      setMessage(res.message || '交易系统已重启')
      await loadSystemStatus()
    } catch (error) {
      setMessage('重启失败: ' + (error.message || '未知错误'))
    } finally {
      setSystemBusy(false)
    }
  }

  const handleRestartBackend = async () => {
    if (!window.confirm('确定要重启后端服务吗？重启期间页面接口会短暂不可用（约 3-10 秒）。')) return
    setSystemBusy(true)
    setMessage('')
    try {
      const res = await api.restartBackend()
      setMessage(res.message || '已发起后端重启')
      // 给后端一点时间完成重启，再刷新状态
      setTimeout(() => {
        loadBackendStatus()
      }, 4000)
    } catch (error) {
      setMessage('重启后端失败: ' + (error.message || '未知错误'))
    } finally {
      setSystemBusy(false)
    }
  }

  const handleRestartAllTrading = async () => {
    if (!window.confirm('确定要重启【所有账号】的交易进程吗？这会让所有用户的交易服务短暂中断（约 3-10 秒），用于升级代码后统一生效。')) return
    setSystemBusy(true)
    setMessage('')
    try {
      const res = await api.restartAllTradingSystems({ prefix: 'auto_sys_acc', do_update: true })
      setMessage(`已发起批量重启：共 ${res.count} 个，成功 ${res.ok}，失败 ${res.failed}`)
    } catch (e) {
      setMessage('批量重启失败: ' + (e?.message || '未知错误'))
    } finally {
      setSystemBusy(false)
    }
  }

  useEffect(() => {
    loadConfigMeta()
    loadConfigs()
    checkFeasibility()
    if (isAdmin) {
      loadSystemStatus()
      loadBackendStatus()
    }
    loadAccountTradingStatus()
    loadCurrentAccountMeta()

    const timer = setInterval(() => {
      if (isAdmin) {
        loadSystemStatus()
        loadBackendStatus()
      }
      loadAccountTradingStatus()
      loadCurrentAccountMeta()
    }, 3000)

    return () => clearInterval(timer)
  }, [])

  const loadAccountsAdmin = async () => {
    try {
      const list = await api.getAccounts()
      setAccountsAdmin(Array.isArray(list) ? list : [])
    } catch (e) {
      setAccountsAdmin([])
    }
  }

  const notifyAccountsUpdated = () => {
    try {
      window.dispatchEvent(new Event('ats:accounts:updated'))
    } catch (e) {
      // ignore
    }
  }

  // 切换账号时，刷新页面数据
  useEffect(() => {
    setCurrentAccountId(accountId)
    setMessage('')
    setLoading(true)
    loadConfigs()
    checkFeasibility()
    if (isAdmin) {
      loadSystemStatus()
      loadBackendStatus()
    }
    loadAccountTradingStatus()
    loadCurrentAccountMeta()
  }, [accountId])

  // 顶部导航切换账号时：即时同步（比 setInterval 更及时）
  useEffect(() => {
    const onChanged = (e) => {
      const next = parseInt(String(e?.detail?.accountId || ''), 10)
      if (Number.isFinite(next) && next > 0) setAccountId(next)
    }
    window.addEventListener('ats:account:changed', onChanged)
    return () => window.removeEventListener('ats:account:changed', onChanged)
  }, [])

  // 顶部导航切换账号时（localStorage更新），这里做一个轻量同步
  useEffect(() => {
    const timer = setInterval(() => {
      const cur = getCurrentAccountId()
      
      if (cur !== accountId) setAccountId(cur)
    }, 1000)
    return () => clearInterval(timer)
  }, [accountId])

  const checkFeasibility = async () => {
    setCheckingFeasibility(true)
    try {
      const result = await api.checkConfigFeasibility()
      setFeasibilityCheck(result)
    } catch (error) {
      console.error('检查配置可行性失败:', error)
      // 静默失败，不显示错误
    } finally {
      setCheckingFeasibility(false)
    }
  }

  const loadConfigs = async () => {
    try {
      const data = await api.getConfigs()
      setConfigs(data)
    } catch (error) {
      console.error('Failed to load configs:', error)
      setMessage('加载配置失败: ' + error.message)
    } finally {
      setLoading(false)
    }
  }

  const handleUpdate = async (key, value, type, category) => {
    setSaving(true)
    setMessage('')
    try {
      const response = await api.updateConfig(key, {
        value,
        type,
        category
      })
      setMessage(response.message || '配置已更新')
      if (response.note) {
        setTimeout(() => {
          setMessage(response.note)
        }, 2000)
      }
      // 重新加载配置
      await loadConfigs()
      // 如果更新的是与可行性相关的配置，重新检查可行性
      if (['MIN_MARGIN_USDT', 'MIN_POSITION_PERCENT', 'MAX_POSITION_PERCENT', 'LEVERAGE'].includes(key)) {
        await checkFeasibility()
      }
    } catch (error) {
      const errorMsg = error.message || '更新失败'
      setMessage('更新失败: ' + errorMsg)
      console.error('Config update error:', error)
    } finally {
      setSaving(false)
    }
  }

  const isSecretKey = (key) => {
    return key === 'BINANCE_API_KEY' || key === 'BINANCE_API_SECRET'
  }

  const maskSecret = (val) => {
    const s = val === null || val === undefined ? '' : String(val)
    if (!s) return ''
    if (s.length <= 8) return '****'
    return `${s.slice(0, 4)}...${s.slice(-4)}`
  }

  const toDisplayValueForSnapshot = (key, value) => {
    if (value === null || value === undefined) return value
    // 百分比/比例：尽量转成 “百分比值”
    if (typeof value === 'number' && (key.includes('PERCENT') || key.includes('PCT'))) {
      // 兼容两种：
      // - 常规 PERCENT/PCT：存储为 0~1（比例），展示为 0~100（%）
      // - PCT_LIKE_KEYS：存储可能是 0.006(=0.6%) 或 0.6(=0.6%)，展示统一为“百分比数值”
      if (PCT_LIKE_KEYS.has(key)) {
        return value <= 0.05 ? value * 100 : value
      }
      return value < 1 ? value * 100 : value
    }
    return value
  }

  const buildConfigSnapshot = async (includeSecrets) => {
    // 为了确保是最新值，这里点击时再拉一次
    const data = await api.getConfigs()
    const now = new Date()

    const categoryMap = {
      scan: '市场扫描',
      position: '仓位控制',
      risk: '风险控制',
      strategy: '策略参数',
      api: 'API配置',
    }

    const entries = Object.entries(data || {}).map(([key, cfg]) => {
      const rawVal = cfg?.value
      const valMasked = isSecretKey(key) && !includeSecrets ? maskSecret(rawVal) : rawVal
      const displayVal = toDisplayValueForSnapshot(key, valMasked)
      return {
        key,
        category: cfg?.category || '',
        category_label: categoryMap[cfg?.category] || cfg?.category || '',
        type: cfg?.type || '',
        value: valMasked,
        display_value: displayVal,
        description: cfg?.description || '',
      }
    })

    // 排序：先分类再按 key
    entries.sort((a, b) => {
      const ca = a.category_label || a.category || ''
      const cb = b.category_label || b.category || ''
      if (ca !== cb) return ca.localeCompare(cb)
      return a.key.localeCompare(b.key)
    })

    const snapshot = {
      fetched_at: now.toISOString(),
      note: 'display_value 对 PERCENT/PCT 做了百分比换算；敏感字段可选择脱敏/明文。',
      preset_detected: detectCurrentPreset(),
      system_status: systemStatus
        ? {
          running: !!systemStatus.running,
          pid: systemStatus.pid || null,
          program: systemStatus.program || null,
          state: systemStatus.state || null,
        }
        : null,
      feasibility_check_summary: feasibilityCheck
        ? {
          feasible: !!feasibilityCheck.feasible,
          account_balance: feasibilityCheck.account_balance ?? null,
          base_leverage: feasibilityCheck.base_leverage ?? feasibilityCheck.leverage ?? null,
          max_leverage: feasibilityCheck.max_leverage ?? null,
          use_dynamic_leverage: feasibilityCheck.use_dynamic_leverage ?? null,
          min_margin_usdt: feasibilityCheck.current_config?.min_margin_usdt ?? null,
        }
        : null,
      configs: entries,
    }

    return JSON.stringify(snapshot, null, 2)
  }

  const openSnapshot = async (includeSecrets) => {
    setSnapshotBusy(true)
    setMessage('')
    try {
      const text = await buildConfigSnapshot(includeSecrets)
      setSnapshotText(text)
      setShowSnapshot(true)
    } catch (e) {
      setMessage('生成配置快照失败: ' + (e?.message || '未知错误'))
    } finally {
      setSnapshotBusy(false)
    }
  }

  const copySnapshot = async () => {
    try {
      if (navigator?.clipboard?.writeText) {
        await navigator.clipboard.writeText(snapshotText || '')
        setMessage('已复制配置快照到剪贴板')
      } else {
        setMessage('当前浏览器不支持剪贴板 API，可手动全选复制')
      }
    } catch (e) {
      setMessage('复制失败: ' + (e?.message || '未知错误'))
    }
  }

  const downloadSnapshot = () => {
    try {
      const blob = new Blob([snapshotText || ''], { type: 'application/json;charset=utf-8' })
      const url = URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = `config-snapshot-${new Date().toISOString().replace(/[:.]/g, '-')}.json`
      document.body.appendChild(a)
      a.click()
      a.remove()
      URL.revokeObjectURL(url)
    } catch (e) {
      setMessage('下载失败: ' + (e?.message || '未知错误'))
    }
  }

  // 检测当前配置匹配哪个预设方案
  const detectCurrentPreset = () => {
    if (!configs || Object.keys(configs).length === 0) return null

    for (const [presetKey, preset] of Object.entries(presets)) {
      let match = true
      for (const [key, expectedValue] of Object.entries(preset.configs)) {
        const currentConfig = configs[key]
        if (!currentConfig) {
          match = false
          break
        }

        // 获取当前值（处理百分比转换）
        let currentValue = currentConfig.value
        if (key.includes('PERCENT') || key.includes('PCT')) {
          if (PCT_LIKE_KEYS.has(key)) {
            // 兼容旧值：0.006(=0.6%) 或 0.6(=0.6%)
            currentValue = currentValue <= 0.05 ? currentValue * 100 : currentValue
          } else {
            currentValue = currentValue * 100
          }
        }

        // 比较值（允许小的浮点数误差）
        if (typeof expectedValue === 'number' && typeof currentValue === 'number') {
          if (Math.abs(currentValue - expectedValue) > 0.01) {
            match = false
            break
          }
        } else if (currentValue !== expectedValue) {
          match = false
          break
        }
      }

      if (match) {
        return presetKey
      }
    }

    return null
  }

  const applyPreset = async (presetKey) => {
    const preset = presets[presetKey]
    if (!preset) return

    setSaving(true)
    setMessage('')
    try {
      const configItems = Object.entries(preset.configs).map(([key, value]) => {
        const config = configs[key]
        if (!config) {
          // 如果配置项不存在，尝试创建（用于新增的配置项）
          // 根据key判断类型和分类
          let type = 'number'
          let category = 'risk'
          if (typeof value === 'boolean') {
            type = 'boolean'
            category = 'strategy'
          }
          if (key.startsWith('ENTRY_') || key.startsWith('SMART_ENTRY_') || key === 'SMART_ENTRY_ENABLED') {
            type = typeof value === 'boolean' ? 'boolean' : 'number'
            category = 'strategy'
          } else if (key.startsWith('AUTO_TRADE_')) {
            type = typeof value === 'boolean' ? 'boolean' : 'number'
            category = 'strategy'
          } else if (key === 'LIMIT_ORDER_OFFSET_PCT') {
            type = 'number'
            category = 'strategy'
          } else if (key.includes('PERCENT') || key.includes('PCT')) {
            type = 'number'
            if (key.includes('STOP_LOSS') || key.includes('TAKE_PROFIT')) {
              category = 'risk'
            } else if (key.includes('POSITION')) {
              category = 'position'
            } else {
              category = 'scan'
            }
          } else if (key === 'MIN_VOLATILITY') {
            type = 'number'
            category = 'scan'
          } else if (typeof value === 'number') {
            type = 'number'
            category = 'scan'
          }

          const detail = typeof getConfigDetail === 'function' ? getConfigDetail(key) : ''
          const desc =
            detail && typeof detail === 'string' && !detail.includes('暂无详细说明')
              ? detail
              : `预设方案配置项：${key}`

          return {
            key,
            value:
              (key.includes('PERCENT') || key.includes('PCT')) && !PCT_LIKE_KEYS.has(key)
                ? value / 100
                : value,
            type,
            category,
            description: desc
          }
        }
        return {
          key,
          value:
            (key.includes('PERCENT') || key.includes('PCT')) && !PCT_LIKE_KEYS.has(key)
              ? value / 100
              : value,
          type: config.type,
          category: config.category,
          description: config.description
        }
      }).filter(Boolean)

      const response = await api.updateConfigsBatch(configItems)
      setMessage(response.message || `已应用${preset.name}`)
      if (response.note) {
        setTimeout(() => {
          setMessage(response.note)
        }, 2000)
      }
      await loadConfigs()
    } catch (error) {
      setMessage('应用预设失败: ' + error.message)
    } finally {
      setSaving(false)
    }
  }

  const currentPreset = detectCurrentPreset()

  if (loading) return <div className="loading">加载中...</div>

  const configCategories = {
    'scan': '市场扫描',
    'position': '仓位控制',
    'risk': '风险控制',
    'strategy': '策略参数',
    'api': 'API配置'
  }

  return (
    <div className="config-panel">
      <div className="config-header">
        <div className="header-top">
          <div className="header-left">
            <h2>交易配置</h2>
            <div className="account-switch">
              <span className="account-hint">当前账号：#{accountId}（在顶部导航切换）</span>
            </div>
            {isAdmin ? (
              <div
                className="system-hint"
                style={{
                  marginTop: '8px',
                  padding: '10px',
                  border: '1px solid #e0b400',
                  background: '#fff8e1',
                }}
              >
                <div style={{ fontWeight: 700 }}>
                  {isGlobalStrategyAccount ? (
                    <>
                      你正在编辑 <span style={{ fontWeight: 900 }}>全局策略账号 #{globalStrategyAccountId}</span>：
                      此处修改将影响所有用户的策略核心。
                    </>
                  ) : (
                    <>
                      你正在编辑账号 #{accountId}：这里只允许调整 <span style={{ fontWeight: 900 }}>风险旋钮</span>（仓位/次数/自动交易开关等）。
                      策略核心统一来自 <span style={{ fontWeight: 900 }}>全局策略账号 #{globalStrategyAccountId}</span>。
                    </>
                  )}
                </div>
                {!isGlobalStrategyAccount ? (
                  <div style={{ marginTop: '8px' }}>
                    <button
                      type="button"
                      className="system-btn primary"
                      onClick={() => {
                        setCurrentAccountId(globalStrategyAccountId)
                        setAccountId(globalStrategyAccountId)
                        setMessage('已切换到全局策略账号（策略核心统一在这里维护）')
                      }}
                    >
                      切换到全局策略账号 #{globalStrategyAccountId}
                    </button>
                  </div>
                ) : null}
              </div>
            ) : null}
          </div>
          <div className="header-actions">
            <button
              type="button"
              className="guide-link snapshot-btn"
              onClick={() => openSnapshot(snapshotIncludeSecrets)}
              disabled={snapshotBusy}
              title="导出当前全量配置（用于分析）"
            >
              {snapshotBusy ? '生成中...' : '查看整体配置'}
            </button>
            <Link to="/config/guide" className="guide-link">📖 配置说明</Link>
          </div>
        </div>
        <div className="config-info">
          <p>修改配置后，交易系统将在下次扫描时自动使用新配置</p>
        </div>

        {/* 我的交易进程（按账号；owner/admin 可启停） */}
        <div className="system-section">
          <div className="system-header">
            <h3>我的交易进程（当前账号 #{accountId}）</h3>
            <div className="system-status">
              <span className={`system-status-badge ${accountTradingStatus?.running ? 'running' : 'stopped'}`}>
                {accountTradingStatus?.running ? '运行中' : '未运行/未知'}
              </span>
              {accountTradingStatus?.pid ? <span className="system-status-meta">PID: {accountTradingStatus.pid}</span> : null}
              {accountTradingStatus?.program ? <span className="system-status-meta">程序: {accountTradingStatus.program}</span> : null}
              {accountTradingStatus?.state ? <span className="system-status-meta">状态: {accountTradingStatus.state}</span> : null}
            </div>
          </div>
          <div className="system-actions">
            <button type="button" className="system-btn" onClick={handleAccountTradingEnsure} disabled={systemBusy} title="为该账号生成/刷新 supervisor program 配置（需要 owner/admin）">
              生成配置
            </button>
            <button type="button" className="system-btn" onClick={handleAccountTradingStop} disabled={systemBusy} title="停止该账号交易进程（需要 owner/admin）">
              停止
            </button>
            <button type="button" className="system-btn" onClick={handleAccountTradingStart} disabled={systemBusy} title="启动该账号交易进程（需要 owner/admin）">
              启动
            </button>
            <button type="button" className="system-btn primary" onClick={handleAccountTradingRestart} disabled={systemBusy} title="重启该账号交易进程（需要 owner/admin）">
              重启
            </button>
          </div>
          <div className="system-hint">
            提示：若按钮报“无权限”，请让管理员在用户授权里把该账号分配为 owner；若报 supervisor 相关错误，请检查后端对 `/www/server/panel/plugin/supervisor` 的写权限与 supervisorctl 可执行权限。
          </div>
          {accountTradingErr ? (
            <div className="system-hint" style={{ color: '#b00020' }}>
              {accountTradingErr}
            </div>
          ) : null}
          {accountTradingStatus?.raw ? (
            <details style={{ marginTop: '8px' }}>
              <summary style={{ cursor: 'pointer' }}>查看原始状态输出</summary>
              <pre style={{ whiteSpace: 'pre-wrap', marginTop: '8px' }}>{String(accountTradingStatus.raw || '')}</pre>
            </details>
          ) : null}
          {accountTradingStatus?.stderr_tail ? (
            <details style={{ marginTop: '8px' }}>
              <summary style={{ cursor: 'pointer' }}>查看最近错误日志（stderr）</summary>
              <pre style={{ whiteSpace: 'pre-wrap', marginTop: '8px' }}>{String(accountTradingStatus.stderr_tail || '')}</pre>
            </details>
          ) : null}
          {accountTradingStatus?.stdout_tail ? (
            <details style={{ marginTop: '8px' }}>
              <summary style={{ cursor: 'pointer' }}>查看最近输出日志（stdout，常见原因在这里）</summary>
              <pre style={{ whiteSpace: 'pre-wrap', marginTop: '8px' }}>{String(accountTradingStatus.stdout_tail || '')}</pre>
            </details>
          ) : null}
          {accountTradingStatus?.stderr_tail_error ? (
            <details style={{ marginTop: '8px' }}>
              <summary style={{ cursor: 'pointer' }}>读取 stderr 失败原因（用于排障）</summary>
              <pre style={{ whiteSpace: 'pre-wrap', marginTop: '8px' }}>{String(accountTradingStatus.stderr_tail_error || '')}</pre>
            </details>
          ) : null}
          {['FATAL', 'EXITED', 'BACKOFF'].includes(String(accountTradingStatus?.state || '')) ? (
            <details style={{ marginTop: '8px' }}>
              <summary style={{ cursor: 'pointer' }}>supervisord 主日志尾部（spawn error 常见原因在这里）</summary>
              <pre style={{ whiteSpace: 'pre-wrap', marginTop: '8px' }}>
                {String(accountTradingStatus?.supervisord_tail || '（暂无：可能未配置 supervisord logfile 或当前用户无权限读取。可在后端配置 SUPERVISOR_LOGFILE 指向 supervisord 主日志路径）')}
              </pre>
            </details>
          ) : null}
        </div>

        {/* 账号密钥（当前账号；owner/admin 可改） */}
        <div className="system-section">
          <div className="system-header">
            <h3>账号密钥（当前账号）</h3>
            <div className="system-status">
              <span className="system-status-meta">说明：为安全起见，页面不会回显 Secret；填入后保存即可。</span>
            </div>
          </div>
          <div className="accounts-form">
            <label>
              API KEY（留空=不改）
              <div className="system-status-meta" style={{ marginTop: '4px' }}>
                当前状态：{currentAccountMeta?.has_api_key ? '已配置（******）' : '未配置（必须先配置才能启动交易）'}
              </div>
              <input
                type="password"
                value={credForm.api_key}
                onChange={(e) => setCredForm({ ...credForm, api_key: e.target.value })}
                placeholder={currentAccountMeta?.has_api_key ? '已配置（******），如需更换请重新填写' : '粘贴你的 Binance API KEY'}
              />
            </label>
            <label>
              API SECRET（留空=不改）
              <div className="system-status-meta" style={{ marginTop: '4px' }}>
                当前状态：{currentAccountMeta?.has_api_secret ? '已配置（******）' : '未配置（必须先配置才能启动交易）'}
              </div>
              <input
                type="password"
                value={credForm.api_secret}
                onChange={(e) => setCredForm({ ...credForm, api_secret: e.target.value })}
                placeholder={currentAccountMeta?.has_api_secret ? '已配置（******），如需更换请重新填写' : '粘贴你的 Binance API SECRET'}
              />
            </label>
            <label className="accounts-inline">
              <span>测试网</span>
              <input
                type="checkbox"
                checked={!!credForm.use_testnet}
                onChange={(e) => setCredForm({ ...credForm, use_testnet: e.target.checked })}
              />
            </label>
            <div className="accounts-form-actions">
              <button
                type="button"
                className="system-btn primary"
                disabled={systemBusy}
                onClick={async () => {
                  setSystemBusy(true)
                  setMessage('')
                  try {
                    const payload = {}
                    if (credForm.api_key) payload.api_key = credForm.api_key
                    if (credForm.api_secret) payload.api_secret = credForm.api_secret
                    payload.use_testnet = !!credForm.use_testnet
                    await api.updateAccountCredentials(accountId, payload)
                    setMessage('密钥已更新（建议重启该账号交易进程）')
                    setCredForm({ api_key: '', api_secret: '', use_testnet: !!credForm.use_testnet })
                  } catch (e) {
                    setMessage('更新密钥失败: ' + (e?.message || '未知错误'))
                  } finally {
                    setSystemBusy(false)
                  }
                }}
              >
                保存密钥
              </button>
            </div>
          </div>
        </div>

        {/* 系统控制：清缓存 / 启停 / 重启（supervisor） */}
        {isAdmin ? (
          <div className="system-section">
            <div className="system-header">
              <h3>系统控制</h3>
              <div className="system-status">
                <span className={`system-status-badge ${systemStatus?.running ? 'running' : 'stopped'}`}>
                  {systemStatus?.running ? '运行中' : '未运行'}
                </span>
                {systemStatus?.pid ? <span className="system-status-meta">PID: {systemStatus.pid}</span> : null}
                {systemStatus?.program ? <span className="system-status-meta">程序: {systemStatus.program}</span> : null}
                {systemStatus?.meta?.requested_at ? <span className="system-status-meta">上次重启: {systemStatus.meta.requested_at}</span> : null}
              </div>
            </div>
            <div className="system-actions">
              <button
                type="button"
                className="system-btn"
                onClick={handleClearCache}
                disabled={systemBusy}
                title="清理Redis配置缓存并从数据库回灌。切换API Key后建议先点这里，再重启交易系统。"
              >
                清除缓存
              </button>
              <button
                type="button"
                className="system-btn"
                onClick={handleStopTrading}
                disabled={systemBusy || systemStatus?.running === false}
                title="通过 supervisorctl 停止交易系统"
              >
                停止
              </button>
              <button
                type="button"
                className="system-btn"
                onClick={handleStartTrading}
                disabled={systemBusy || systemStatus?.running === true}
                title="通过 supervisorctl 启动交易系统"
              >
                启动
              </button>
              <button
                type="button"
                className="system-btn primary"
                onClick={handleRestartTrading}
                disabled={systemBusy}
                title="通过 supervisorctl 重启交易系统（建议切换API Key后使用）"
              >
                重启交易系统
              </button>
              <button
                type="button"
                className="system-btn primary"
                onClick={handleRestartAllTrading}
                disabled={systemBusy}
                title="批量重启所有账号交易进程（auto_sys_acc*），用于代码升级后统一生效"
              >
                重启所有账号交易
              </button>
              <button
                type="button"
                className="system-btn primary"
                onClick={handleRestartBackend}
                disabled={systemBusy}
                title="通过 backend/restart.sh 重启后端（uvicorn）。重启期间接口会短暂不可用。"
              >
                重启后端服务
              </button>
            </div>
            <div className="system-status" style={{ marginTop: '10px' }}>
              <span className={`system-status-badge ${backendStatus?.running ? 'running' : 'stopped'}`}>
                后端 {backendStatus?.running ? '运行中' : '未知'}
              </span>
              {backendStatus?.pid ? <span className="system-status-meta">PID: {backendStatus.pid}</span> : null}
              {backendStatus?.meta?.requested_at ? <span className="system-status-meta">上次重启: {backendStatus.meta.requested_at}</span> : null}
            </div>
            <div className="system-hint">
              建议流程：先更新配置里的 Key → 点击“清除缓存” → 点击“重启交易系统”，确保不再使用旧账号下单。
            </div>
          </div>
        ) : null}

        {/* 账号管理（超管） */}
        {isAdmin ? (
          <div className="accounts-admin-section">
            <div className="accounts-admin-header">
              <h3>账号管理（多账号）</h3>
              <div className="accounts-admin-actions">
                <button
                  type="button"
                  className="system-btn"
                  onClick={async () => {
                    setAccountsBusy(true)
                    try {
                      await loadAccountsAdmin()
                      setShowAccountsAdmin((v) => !v)
                    } finally {
                      setAccountsBusy(false)
                    }
                  }}
                  disabled={accountsBusy}
                  title="创建/禁用账号；为每个账号配置独立 API KEY/SECRET；交易/配置/统计会按账号隔离"
                >
                  {showAccountsAdmin ? '收起' : '管理账号'}
                </button>
                <button
                  type="button"
                  className="system-btn"
                  onClick={async () => {
                    setAccountsBusy(true)
                    try {
                      await loadAccountsAdmin()
                      notifyAccountsUpdated()
                      setMessage('账号列表已刷新')
                    } finally {
                      setAccountsBusy(false)
                    }
                  }}
                  disabled={accountsBusy}
                >
                  刷新
                </button>
              </div>
            </div>

            {showAccountsAdmin ? (
              <div className="accounts-admin-body">
                <div className="accounts-admin-card">
                  <div className="accounts-admin-card-title">新增账号</div>
                  <div className="accounts-form">
                    <label>
                      名称
                      <input
                        type="text"
                        value={newAccount.name}
                        onChange={(e) => setNewAccount({ ...newAccount, name: e.target.value })}
                        placeholder="例如：user_a"
                      />
                    </label>
                    <label>
                      API KEY
                      <input
                        type="password"
                        value={newAccount.api_key}
                        onChange={(e) => setNewAccount({ ...newAccount, api_key: e.target.value })}
                        placeholder="可先留空，后续再填"
                      />
                    </label>
                    <label>
                      API SECRET
                      <input
                        type="password"
                        value={newAccount.api_secret}
                        onChange={(e) => setNewAccount({ ...newAccount, api_secret: e.target.value })}
                        placeholder="可先留空，后续再填"
                      />
                    </label>
                    <label className="accounts-inline">
                      <span>测试网</span>
                      <input
                        type="checkbox"
                        checked={!!newAccount.use_testnet}
                        onChange={(e) => setNewAccount({ ...newAccount, use_testnet: e.target.checked })}
                      />
                    </label>
                    <label>
                      状态
                      <select
                        value={newAccount.status}
                        onChange={(e) => setNewAccount({ ...newAccount, status: e.target.value })}
                      >
                        <option value="active">启用</option>
                        <option value="disabled">禁用</option>
                      </select>
                    </label>
                    <div className="accounts-form-actions">
                      <button
                        type="button"
                        className="system-btn primary"
                        disabled={accountsBusy || !newAccount.name.trim()}
                        onClick={async () => {
                          setAccountsBusy(true)
                          setMessage('')
                          try {
                            await api.createAccount(newAccount)
                            setMessage('账号已创建')
                            setNewAccount({ name: '', api_key: '', api_secret: '', use_testnet: false, status: 'active' })
                            await loadAccountsAdmin()
                            notifyAccountsUpdated()
                          } catch (e) {
                            setMessage('创建账号失败: ' + (e?.message || '未知错误'))
                          } finally {
                            setAccountsBusy(false)
                          }
                        }}
                      >
                        创建账号
                      </button>
                    </div>
                  </div>
                </div>

                <div className="accounts-admin-card">
                  <div className="accounts-admin-card-title">账号列表</div>
                  <div className="accounts-table">
                    {(accountsAdmin || []).length ? (
                      <table>
                        <thead>
                          <tr>
                            <th>ID</th>
                            <th>名称</th>
                            <th>状态</th>
                            <th>测试网</th>
                            <th>API KEY</th>
                            <th>SECRET</th>
                            <th>操作</th>
                          </tr>
                        </thead>
                        <tbody>
                          {accountsAdmin.map((a) => (
                            <tr key={a.id}>
                              <td>#{a.id}</td>
                              <td>{a.name || '-'}</td>
                              <td>
                                <span className={`acct-badge ${a.status === 'active' ? 'ok' : 'off'}`}>
                                  {a.status === 'active' ? '启用' : '禁用'}
                                </span>
                              </td>
                              <td>{a.use_testnet ? '是' : '否'}</td>
                              <td>{a.api_key_masked || (a.has_api_key ? '已配置' : '未配置')}</td>
                              <td>{a.has_api_secret ? '已配置' : '未配置'}</td>
                              <td className="accounts-actions-cell">
                                <button
                                  type="button"
                                  className="system-btn"
                                  disabled={accountsBusy || a.id === 1}
                                  title={a.id === 1 ? '默认账号建议保留' : '切换启用/禁用'}
                                  onClick={async () => {
                                    setAccountsBusy(true)
                                    setMessage('')
                                    try {
                                      const next = a.status === 'active' ? 'disabled' : 'active'
                                      await api.updateAccount(a.id, { status: next })
                                      await loadAccountsAdmin()
                                      notifyAccountsUpdated()
                                      setMessage(`账号 #${a.id} 已${next === 'active' ? '启用' : '禁用'}`)
                                    } catch (e) {
                                      setMessage('更新账号失败: ' + (e?.message || '未知错误'))
                                    } finally {
                                      setAccountsBusy(false)
                                    }
                                  }}
                                >
                                  {a.status === 'active' ? '禁用' : '启用'}
                                </button>
                                <button
                                  type="button"
                                  className="system-btn"
                                  disabled={accountsBusy}
                                  onClick={() => {
                                    setCredEditId(a.id)
                                    setCredForm({ api_key: '', api_secret: '', use_testnet: !!a.use_testnet })
                                  }}
                                >
                                  更新密钥
                                </button>
                              </td>
                            </tr>
                          ))}
                        </tbody>
                      </table>
                    ) : (
                      <div className="accounts-empty">暂无账号（默认账号 #1 会自动存在）</div>
                    )}
                  </div>
                </div>

                {credEditId ? (
                  <div className="accounts-admin-card">
                    <div className="accounts-admin-card-title">更新账号 #{credEditId} 的密钥</div>
                    <div className="accounts-form">
                      <label>
                        API KEY（留空=不改）
                        <input
                          type="password"
                          value={credForm.api_key}
                          onChange={(e) => setCredForm({ ...credForm, api_key: e.target.value })}
                        />
                      </label>
                      <label>
                        API SECRET（留空=不改）
                        <input
                          type="password"
                          value={credForm.api_secret}
                          onChange={(e) => setCredForm({ ...credForm, api_secret: e.target.value })}
                        />
                      </label>
                      <label className="accounts-inline">
                        <span>测试网</span>
                        <input
                          type="checkbox"
                          checked={!!credForm.use_testnet}
                          onChange={(e) => setCredForm({ ...credForm, use_testnet: e.target.checked })}
                        />
                      </label>
                      <div className="accounts-form-actions">
                        <button
                          type="button"
                          className="system-btn"
                          disabled={accountsBusy}
                          onClick={() => setCredEditId(null)}
                        >
                          取消
                        </button>
                        <button
                          type="button"
                          className="system-btn primary"
                          disabled={accountsBusy}
                          onClick={async () => {
                            setAccountsBusy(true)
                            setMessage('')
                            try {
                              const payload = {}
                              if (credForm.api_key) payload.api_key = credForm.api_key
                              if (credForm.api_secret) payload.api_secret = credForm.api_secret
                              payload.use_testnet = !!credForm.use_testnet
                              await api.updateAccountCredentials(credEditId, payload)
                              setMessage(`账号 #${credEditId} 密钥已更新（建议重启该账号交易进程）`)
                              setCredEditId(null)
                              await loadAccountsAdmin()
                              notifyAccountsUpdated()
                            } catch (e) {
                              setMessage('更新密钥失败: ' + (e?.message || '未知错误'))
                            } finally {
                              setAccountsBusy(false)
                            }
                          }}
                        >
                          保存
                        </button>
                      </div>
                    </div>
                  </div>
                ) : null}
              </div>
            ) : null}
          </div>
        ) : null}

        {/* 预设方案快速切换（仅管理员 + 全局策略账号：策略核心统一管理） */}
        {isAdmin && isGlobalStrategyAccount ? (
          <div className="preset-section">
            <div className="preset-header">
              <h3>快速切换方案</h3>
              <div className="current-preset-status">
                <span className="status-label">当前方案：</span>
                <span className={`status-badge ${currentPreset ? 'preset' : 'custom'}`}>
                  {currentPreset ? presets[currentPreset].name : '自定义'}
                </span>
              </div>
            </div>
            <div className="preset-guide">
              <div className="preset-guide-title">怎么选更不迷糊</div>
              <ul className="preset-guide-list">
                <li>
                  <strong>先选入场机制</strong>：纯限价（更控频但可能撤单） vs 智能入场（更少漏单但需限制追价）。
                </li>
                <li>
                  <strong>再看“会不会下单”</strong>：如果你发现几乎不出单，优先把 <code>AUTO_TRADE_ONLY_TRENDING</code> 关掉、把 <code>AUTO_TRADE_ALLOW_4H_NEUTRAL</code> 打开。
                </li>
                <li>
                  <strong>最后再微调</strong>：想更容易成交 → 调小 <code>LIMIT_ORDER_OFFSET_PCT</code>、调大 <code>ENTRY_CONFIRM_TIMEOUT_SEC</code>。
                </li>
              </ul>
            </div>

            {(() => {
            const presetUiMeta = {
              swing: { group: 'limit', tag: '纯限价' },
              strict: { group: 'limit', tag: '纯限价' },
              fill: { group: 'smart', tag: '智能入场' },
              steady: { group: 'smart', tag: '智能入场' },
              conservative: { group: 'legacy', tag: '传统' },
              balanced: { group: 'legacy', tag: '传统' },
              aggressive: { group: 'legacy', tag: '高频实验' },
            }

            const groups = [
              {
                key: 'limit',
                title: 'A. 纯限价（SMART_ENTRY_ENABLED=false）',
                desc: '只下 1 次限价单，未在确认时间内成交就撤单跳过。更控频、更接近“波段”，但更容易出现 NEW→撤单。',
                presetKeys: ['swing', 'strict'],
              },
              {
                key: 'smart',
                title: 'B. 智能入场（SMART_ENTRY_ENABLED=true）',
                desc: '限价回调 + 受限追价 +（趋势强时）可控市价兜底。更少漏单，但必须限制追价步数与偏离上限，避免回到高频追价。',
                presetKeys: ['fill', 'steady'],
              },
              {
                key: 'legacy',
                title: 'C. 传统 / 实验（不建议长期）',
                desc: '这组更多用于对比或临时实验（频率更高/更容易过度交易），建议在稳定盈利前谨慎使用。',
                presetKeys: ['conservative', 'balanced', 'aggressive'],
              },
            ]

            return (
              <div className="preset-groups">
                {groups.map((g) => (
                  <div key={g.key} className="preset-group">
                    <div className="preset-group-header">
                      <div className="preset-group-title">{g.title}</div>
                      <div className="preset-group-desc">{g.desc}</div>
                    </div>
                    <div className="preset-buttons">
                      {g.presetKeys
                        .filter((k) => presets[k])
                        .map((k) => {
                          const preset = presets[k]
                          const meta = presetUiMeta[k] || { group: g.key, tag: '' }
                          return (
                            <button
                              key={k}
                              className={`preset-btn ${currentPreset === k ? 'active' : ''}`}
                              onClick={() => applyPreset(k)}
                              disabled={saving}
                              title={preset.desc}
                            >
                              <div className="preset-name">
                                {preset.name}
                                {meta.tag ? (
                                  <span className={`preset-tag preset-tag--${meta.group}`}>{meta.tag}</span>
                                ) : null}
                                {currentPreset === k ? <span className="active-indicator">✓</span> : null}
                              </div>
                              <div className="preset-desc">{preset.desc}</div>
                            </button>
                          )
                        })}
                    </div>
                  </div>
                ))}
              </div>
            )
            })()}
          </div>
        ) : (
          <div className="system-hint" style={{ marginTop: '12px' }}>
            平台已开启“傻瓜化模式”：策略核心由管理员统一管理。你只需要配置密钥、充值余额，并调整少量风控参数（如最小/最大仓位、每日开仓次数等）。
          </div>
        )}
      </div>

      {/* 配置可行性检查提示 */}
      {feasibilityCheck && (
        <div className={`feasibility-check ${feasibilityCheck.feasible ? 'feasible' : 'infeasible'}`}>
          <div className="feasibility-header">
            <h4>
              {feasibilityCheck.feasible ? '✓ 配置可行' : '⚠ 配置冲突'}
            </h4>
            <button
              onClick={checkFeasibility}
              disabled={checkingFeasibility}
              className="refresh-btn"
              title="重新检查"
            >
              {checkingFeasibility ? '检查中...' : '🔄 刷新'}
            </button>
          </div>
          <div className="feasibility-info">
            <p>
              账户余额: <strong>{feasibilityCheck.account_balance?.toFixed(2) || 'N/A'}</strong> USDT |
              基础杠杆: <strong>{feasibilityCheck.base_leverage || feasibilityCheck.leverage || 'N/A'}x</strong>
              {feasibilityCheck.use_dynamic_leverage && feasibilityCheck.max_leverage && (
                <> | 最大杠杆: <strong>{feasibilityCheck.max_leverage}x</strong></>
              )} |
              最小保证金: <strong>{feasibilityCheck.current_config?.min_margin_usdt?.toFixed(2) || 'N/A'}</strong> USDT
            </p>
            {!feasibilityCheck.feasible && (
              <div className="warning-text">
                <p>
                  需要保证金占比: <strong>{feasibilityCheck.calculated_values?.required_position_percent?.toFixed(1)}%</strong> |
                  最大允许保证金占比: <strong>{feasibilityCheck.calculated_values?.max_allowed_position_percent?.toFixed(1)}%</strong>
                </p>
                {feasibilityCheck.calculated_values?.actual_min_margin !== undefined && (
                  <p>
                    最小保证金占比可提供保证金: <strong>{feasibilityCheck.calculated_values.actual_min_margin.toFixed(2)} USDT</strong>
                    (MIN_POSITION_PERCENT={feasibilityCheck.calculated_values.min_position_percent?.toFixed(1)}%) |
                    最小保证金要求: <strong>{feasibilityCheck.current_config?.min_margin_usdt?.toFixed(2)} USDT</strong>
                  </p>
                )}
              </div>
            )}
          </div>
          {feasibilityCheck.suggestions && feasibilityCheck.suggestions.length > 0 && (
            <div className="feasibility-suggestions">
              <h5>建议方案：</h5>
              {feasibilityCheck.suggestions.map((suggestion, index) => {
                // 如果是杠杆分析结果，显示详细表格
                if (suggestion.type === 'leverage_analysis' && suggestion.leverage_results) {
                  return (
                    <div key={index} className="suggestion-item leverage-analysis">
                      <div className="suggestion-header">
                        <strong>{suggestion.title}</strong>
                      </div>
                      <div className="leverage-table">
                        <table>
                          <thead>
                            <tr>
                              <th>杠杆倍数</th>
                              <th>需要保证金(USDT)</th>
                              <th>需要保证金%</th>
                              <th>实际最小保证金</th>
                              <th>状态</th>
                            </tr>
                          </thead>
                          <tbody>
                            {suggestion.leverage_results.map((result, idx) => (
                              <tr key={idx} className={result.feasible ? 'feasible-row' : 'infeasible-row'}>
                                <td><strong>{result.leverage}x</strong></td>
                                <td>{result.required_position_value.toFixed(2)} USDT</td>
                                <td>{result.required_position_percent.toFixed(1)}%</td>
                                <td>{result.actual_min_margin.toFixed(2)} USDT</td>
                                <td>
                                  <span className={result.feasible ? 'status-ok' : 'status-error'}>
                                    {result.feasible ? '✓ 可行' : '✗ 不可行'}
                                  </span>
                                </td>
                              </tr>
                            ))}
                          </tbody>
                        </table>
                      </div>
                    </div>
                  )
                }

                // 普通建议
                return (
                  <div key={index} className="suggestion-item">
                    <div className="suggestion-header">
                      <strong>{suggestion.title}</strong>
                    </div>
                    <p className="suggestion-desc">{suggestion.description}</p>
                    {suggestion.config_key && suggestion.suggested_value !== null && (
                      <button
                        className="apply-suggestion-btn"
                        onClick={async () => {
                          try {
                            await api.updateConfig(suggestion.config_key, {
                              value: suggestion.suggested_value,
                              type: 'number',
                              category: 'position'
                            })
                            setMessage(`已应用建议: ${suggestion.title}`)
                            await loadConfigs()
                            await checkFeasibility()
                          } catch (error) {
                            setMessage('应用建议失败: ' + error.message)
                          }
                        }}
                      >
                        应用此建议
                      </button>
                    )}
                  </div>
                )
              })}
            </div>
          )}
        </div>
      )}

      {message && (
        <div className={`message ${message.includes('失败') || message.includes('错误') ? 'error' : 'success'}`}>
          {message}
        </div>
      )}

      {Object.entries(configCategories).map(([category, label]) => (
        <section key={category} className="config-section">
          <h3>{label}</h3>
          <div className="config-grid">
            {Object.entries(configs)
              .filter(([key, config]) => {
                if (config.category !== category) return false
                // 密钥相关配置统一在“账号密钥（当前账号）”模块管理，这里不重复展示
                if (key === 'BINANCE_API_KEY' || key === 'BINANCE_API_SECRET' || key === 'USE_TESTNET') return false
                return true
              })
              .map(([key, config]) => (
                <ConfigItem
                  key={key}
                  label={key}
                  config={config}
                  onUpdate={(value) => handleUpdate(key, value, config.type, config.category)}
                  disabled={saving}
                />
              ))}
          </div>
        </section>
      ))}

      {showSnapshot && (
        <div className="snapshot-modal-overlay" onClick={() => setShowSnapshot(false)} role="presentation">
          <div className="snapshot-modal" onClick={(e) => e.stopPropagation()}>
            <div className="snapshot-modal-header">
              <div>
                <h3>当前整体配置快照</h3>
                <div className="snapshot-hint">
                  默认脱敏 BINANCE_API_KEY/SECRET。你可以选择明文后重新生成再复制/下载。
                </div>
              </div>
              <button type="button" className="snapshot-close" onClick={() => setShowSnapshot(false)}>
                关闭
              </button>
            </div>

            <div className="snapshot-toolbar">
              <label className="snapshot-checkbox">
                <input
                  type="checkbox"
                  checked={snapshotIncludeSecrets}
                  onChange={async (e) => {
                    const checked = e.target.checked
                    setSnapshotIncludeSecrets(checked)
                    // 重新生成（确保脱敏/明文一致）
                    await openSnapshot(checked)
                  }}
                />
                显示敏感信息（明文）
              </label>

              <div className="snapshot-actions">
                <button type="button" className="system-btn" onClick={copySnapshot}>
                  复制
                </button>
                <button type="button" className="system-btn primary" onClick={downloadSnapshot}>
                  下载 JSON
                </button>
              </div>
            </div>

            <pre className="snapshot-pre">{snapshotText}</pre>
          </div>
        </div>
      )}
    </div>
  )
}

const ConfigItem = ({ label, config, onUpdate, disabled }) => {
  const isPercentKey = label.includes('PERCENT') || label.includes('PCT')
  const PCT_LIKE_KEYS = new Set([
    'LIMIT_ORDER_OFFSET_PCT',
    'ENTRY_MAX_DRIFT_PCT_TRENDING',
    'ENTRY_MAX_DRIFT_PCT_RANGING',
  ])
  const isPctLike = PCT_LIKE_KEYS.has(label)
  const isRatioPercentKey = isPercentKey && !isPctLike

  const formatPercent = (n) => {
    // 最多 4 位小数，去掉尾随 0（例如 2.3000 -> 2.3）
    if (typeof n !== 'number' || isNaN(n)) return ''
    return n.toFixed(4).replace(/\.?0+$/, '')
  }

  // 初始化显示值：百分比配置转为“百分比数值”（支持小数）
  const getInitialDisplayValue = (val) => {
    if (config.type === 'number' && isPercentKey) {
      if (val === null || val === undefined || val === '') {
        return ''
      }
      const numVal = typeof val === 'string' ? parseFloat(val) : val
      if (isNaN(numVal)) {
        return ''
      }
      // 两类：
      // 1) 常规比例型（如 STOP_LOSS_PERCENT=0.08）：展示为 8（%）
      // 2) pct-like（如 LIMIT_ORDER_OFFSET_PCT=0.5 表示0.5%）：展示为 0.5（%）
      if (isPctLike) {
        const pctNum = numVal <= 0.05 ? numVal * 100 : numVal
        return formatPercent(pctNum)
      }
      const percent = numVal <= 1 ? numVal * 100 : numVal
      return formatPercent(percent)
    }
    return val === null || val === undefined ? '' : val
  }

  const [value, setValue] = useState(config.value)
  const [localValue, setLocalValue] = useState(getInitialDisplayValue(config.value))
  const [isEditing, setIsEditing] = useState(false)
  const [showDetail, setShowDetail] = useState(false)

  useEffect(() => {
    setValue(config.value)
    // 当配置值更新时，重置编辑状态和本地值
    setIsEditing(false)
    setLocalValue(getInitialDisplayValue(config.value))
  }, [config.value])

  const handleChange = (newValue) => {
    setLocalValue(newValue)
    setIsEditing(true)
  }

  const handleSave = () => {
    setIsEditing(false)

    // 处理localValue可能是字符串的情况
    let processedValue = localValue
    if (config.type === 'number') {
      // 如果是空字符串，恢复原值
      if (localValue === '' || localValue === null || localValue === undefined) {
        setLocalValue(value)
        return
      }

      // 处理字符串形式的数字输入（包括部分输入如 "0." 或 "."）
      let numValue
      if (typeof localValue === 'string') {
        // 如果字符串以 "." 结尾（如 "0." 或 "."），尝试补全为有效数字
        if (localValue.endsWith('.') && localValue.length > 1) {
          // "0." -> 0, "1." -> 1
          numValue = parseFloat(localValue)
        } else if (localValue === '.' || localValue === '-.') {
          // "." 或 "-." 视为无效，恢复原值
          const restoreValue = isPercentKey
            ? (typeof value === 'number' ? formatPercent((value <= 1 ? value * 100 : value)) : value)
            : value
          setLocalValue(restoreValue)
          return
        } else {
          numValue = parseFloat(localValue)
        }
      } else {
        numValue = localValue
      }

      if (isNaN(numValue)) {
        // 如果输入无效，恢复原值
        const restoreValue = isPercentKey
          ? (typeof value === 'number' ? formatPercent((value <= 1 ? value * 100 : value)) : value)
          : value
        setLocalValue(restoreValue)
        return
      }

      processedValue = numValue
      // 百分比配置
      if (isPercentKey) {
        if (isPctLike) {
          // pct-like：值本身就是“百分比数值”（<=1表示<=1%），不做 /100
          if (processedValue < 0 || processedValue > 1) {
            setLocalValue(getInitialDisplayValue(value))
            return
          }
        } else {
          // 常规比例型：前端按“百分比”输入（0~100），存储为 0~1
          if (processedValue < 0 || processedValue > 100) {
            setLocalValue(getInitialDisplayValue(value))
            return
          }
          processedValue = processedValue / 100
        }
      }
    } else if (config.type === 'boolean') {
      processedValue = localValue === 'true' || localValue === true
    }

    // 只有当值真正发生变化时才保存
    if (processedValue !== value) {
      onUpdate(processedValue)
    } else {
      // 值没变化，但需要更新显示值
      setValue(processedValue)
    }
  }

  const handleBlur = () => {
    // 移动端不自动保存，需要点击保存按钮
    if (window.innerWidth > 768) {
      handleSave()
    }
  }

  const handleKeyPress = (e) => {
    if (e.key === 'Enter') {
      handleSave()
    }
  }

  const displayValue = localValue === null || localValue === undefined ? '' : localValue

  if (config.type === 'boolean') {
    return (
      <div className="config-item">
        <div className="config-item-header">
          <label>{label}</label>
          {config.description && (
            <button
              className="help-btn"
              onClick={() => setShowDetail(!showDetail)}
              type="button"
            >
              {showDetail ? '收起' : '说明'}
            </button>
          )}
        </div>
        {showDetail && (
          <div className="config-detail-popup">
            {getConfigDetail(label)}
          </div>
        )}
        <select
          value={localValue ? 'true' : 'false'}
          onChange={(e) => {
            handleChange(e.target.value)
            // 布尔值立即保存
            onUpdate(e.target.value === 'true')
          }}
          disabled={disabled}
        >
          <option value="true">是</option>
          <option value="false">否</option>
        </select>
        {config.description && (
          <span className="description">
            {config.description}
          </span>
        )}
      </div>
    )
  }

  if (label.includes('INTERVAL') && ['PRIMARY_INTERVAL', 'CONFIRM_INTERVAL', 'ENTRY_INTERVAL', 'KLINE_INTERVAL'].includes(label)) {
    const options = ['1m', '3m', '5m', '15m', '30m', '1h', '2h', '4h', '1d']
    return (
      <div className="config-item">
        <div className="config-item-header">
          <label>{label}</label>
          {config.description && (
            <button
              className="help-btn"
              onClick={() => setShowDetail(!showDetail)}
              type="button"
            >
              {showDetail ? '收起' : '说明'}
            </button>
          )}
        </div>
        {showDetail && (
          <div className="config-detail-popup">
            {getConfigDetail(label)}
          </div>
        )}
        <select
          value={localValue}
          onChange={(e) => {
            handleChange(e.target.value)
            // 下拉框立即保存
            onUpdate(e.target.value)
          }}
          disabled={disabled}
        >
          {options.map(opt => (
            <option key={opt} value={opt}>{opt}</option>
          ))}
        </select>
        {config.description && (
          <span className="description">
            {config.description}
          </span>
        )}
      </div>
    )
  }

  return (
    <div className="config-item">
      <div className="config-item-header">
        <label>{label}</label>
        {config.description && (
          <button
            className="help-btn"
            onClick={() => setShowDetail(!showDetail)}
            type="button"
          >
            {showDetail ? '收起' : '说明'}
          </button>
        )}
      </div>
      {showDetail && (
        <div className="config-detail-popup">
          {getConfigDetail(label)}
        </div>
      )}
      <div className="config-input-wrapper">
        <input
          type="text"
          inputMode={config.type === 'number' ? 'decimal' : 'text'}
          value={displayValue === '' ? '' : String(displayValue)}
          onChange={(e) => {
            // 使用文本输入，避免number类型的自动补0问题
            let newValue = e.target.value

            // 对于数字类型，只允许数字、小数点和负号
            if (config.type === 'number') {
              // 允许空字符串、数字、小数点和负号
              // const validPattern = /^-?\d*\.?\d*$/
              // if (newValue !== '' && !validPattern.test(newValue)) {
              //   // 无效输入，不更新
              //   return
              // }

              // 如果是百分比配置，限制输入范围（0-100）
              if (isPercentKey) {
                const numValue = parseFloat(newValue)
                const maxAllowed = isPctLike ? 1 : 100
                if (newValue !== '' && !isNaN(numValue) && (numValue < 0 || numValue > maxAllowed)) {
                  // 超出范围，不更新
                  return
                }
              }
            }

            // 更新本地值
            if (config.type === 'number' && isPercentKey) {
              // 百分比配置：允许字符串中间态（如 "2."），并支持小数
              if (newValue === '') {
                handleChange('')
              } else {
                const validPattern = /^-?\d*\.?\d*$/
                if (validPattern.test(newValue)) {
                  handleChange(newValue)
                }
              }
            } else if (config.type === 'number') {
              // 其他数字配置：允许字符串形式的中间状态（如 "0." 或 "."），支持小数输入
              if (newValue === '') {
                handleChange('')
              } else {
                // 允许部分输入状态（如 "0.", ".5", "-" 等）
                // 使用正则验证是否为有效的数字格式（包括部分输入）
                const validPattern = /^-?\d*\.?\d*$/
                if (validPattern.test(newValue)) {
                  // 如果是有效的数字格式（包括部分输入），直接保存字符串
                  handleChange(newValue)
                }
                // 如果无效，不更新（保持原值）
              }
            } else {
              handleChange(newValue)
            }
          }}
          onBlur={handleBlur}
          onKeyPress={handleKeyPress}
          onKeyDown={(e) => {
            // 允许删除、退格、方向键等
            if (['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab'].includes(e.key)) {
              return
            }
            // 对于数字输入，只允许数字、小数点和负号
            if (config.type === 'number') {
              const currentValue = String(localValue || '')
              // 如果已经包含小数点，不允许再次输入小数点
              if (e.key === '.' && currentValue.includes('.')) {
                e.preventDefault()
                return
              }
              // 如果已经包含负号，不允许再次输入负号（除非是删除操作）
              if (e.key === '-' && currentValue.includes('-')) {
                e.preventDefault()
                return
              }
              const validKeys = /^[0-9.-]$/
              if (!validKeys.test(e.key) && !['Enter', 'Escape'].includes(e.key)) {
                e.preventDefault()
              }
            }
          }}
          disabled={disabled}
          className={isEditing ? 'editing' : ''}
          placeholder={isPercentKey ? (isPctLike ? '输入0~1（表示0%~1%）' : '输入百分比（可小数）') : '输入数值'}
        />
        {isPercentKey && <span className="percent-suffix">%</span>}
        {isEditing && (
          <button
            className="save-btn"
            onClick={handleSave}
            disabled={disabled}
            type="button"
          >
            保存
          </button>
        )}
      </div>
      {isEditing && window.innerWidth > 768 && <span className="edit-hint">按Enter保存</span>}
      {config.description && (
        <span className="description">
          {config.description}
        </span>
      )}
    </div>
  )
}

// 配置项详细说明
const getConfigDetail = (key) => {
  const details = {
    // 市场扫描参数
    'SCAN_INTERVAL': '扫描间隔（秒）。系统每隔多长时间扫描一次市场寻找交易机会。值越小扫描越频繁，能更快捕捉波动，但更容易产生噪音与过度交易。建议：低频波段1800秒(30分钟)或更长；稳健/保守可3600秒(1小时)；高频不建议长期使用。',
    'MIN_CHANGE_PERCENT': '最小涨跌幅阈值（%）。只有24小时涨跌幅达到此值的交易对才会被考虑交易。值越小捕捉机会越多，但可能包含噪音和假信号。值越大只捕捉大幅波动，信号质量更高但机会更少。建议：保守策略2.0-3.0%，平衡策略1.5-2.0%，激进策略1.0-1.5%。',
    'MIN_SIGNAL_STRENGTH': '最小信号强度（0-10）。技术指标综合评分，只有达到此强度的信号才会执行交易。值越小机会越多但噪音更大；值越大更偏“精选高质量”。建议：低频波段建议≥8；一般保守5-7；平衡4-5；高频3-4（不推荐长期）。',
    'TOP_N_SYMBOLS': '每次扫描后处理的交易对数量。从符合条件的交易对中选择涨跌幅最大的前N个进行详细分析。值越大机会越多，但计算量增加，API请求增多。建议：保守策略8-10个，平衡策略12-15个，激进策略15-20个。',
    'MAX_SCAN_SYMBOLS': '扫描的最大交易对数量（0表示扫描所有）。限制每次扫描时处理的交易对总数，减少API请求和计算量。值越小扫描越快，但可能错过一些机会。值越大覆盖更全面，但API请求和计算量增加。建议：保守策略100-200个，平衡策略200-300个，激进策略300-500个。设置为0会扫描所有交易对（约500+个）。',
    'MIN_VOLATILITY': '最小波动率（小数形式，如0.02表示2%）。过滤掉波动率低于此值的交易对，确保只交易有足够波动的币种。值越小允许更多交易对，但可能包含波动不足的币种。值越大只交易高波动币种，但可能错过一些机会。建议：0.015-0.025（1.5%-2.5%）。',
    'MIN_VOLUME_24H': '最小24小时成交量（USDT）。过滤掉24小时交易量低于此值的交易对，确保只交易流动性好的币种，避免滑点和流动性风险。建议：≥500万USDT，主流币种可设置1000万以上。',
    'KLINE_INTERVAL': 'K线数据周期。获取K线数据的基础周期，影响技术指标的计算粒度。周期越短反应越快，但可能包含更多噪音。周期越长信号更平滑，但反应较慢。建议：5m-1h，通常与PRIMARY_INTERVAL保持一致。',
    'PRIMARY_INTERVAL': '主周期。策略分析的主要时间周期，用于计算技术指标（RSI、MACD、布林带等）。决定策略主要关注的市场趋势级别。周期越短反应越快，周期越长趋势更明确。建议：保守策略4h-1d，平衡策略1h-4h，激进策略15m-1h。',
    'CONFIRM_INTERVAL': '确认周期。用于确认交易信号的更长时间周期，增加信号的可靠性，减少假信号。通常比主周期更长。建议：保守策略1d，平衡策略4h-1d，激进策略1h-4h。',
    'ENTRY_INTERVAL': '入场周期。用于精确入场的短时间周期，优化入场点，提高单笔交易的盈亏比。通常比主周期更短。建议：保守策略1h，平衡策略15m-30m，激进策略5m-15m。',

    // 仓位控制参数
    'MAX_POSITION_PERCENT': '单笔最大保证金占用（账户余额的百分比，如0.02表示2%）。系统会先按该比例分配“保证金”，再根据杠杆换算名义价值下单。值越小越保守，适合回归波段交易、降低单笔波动对账户的伤害。注意：币安合约有最小名义价值要求（通常≥5 USDT），如果保证金过小且杠杆不够，系统会提示无法满足最小名义价值。',
    'MAX_TOTAL_POSITION_PERCENT': '总保证金上限（账户余额的百分比，如0.20表示20%）。所有持仓占用的保证金之和不能超过该上限，防止过度分散和风险集中。值越小越易控仓，便于管理持仓数量与节奏。',
    'MIN_POSITION_PERCENT': '单笔最小保证金占用（账户余额的百分比，如0.01表示1%）。用于避免过小仓位（意义不大、易受手续费影响）。如果你希望取消这一限制，可设置为0（等价于关闭最小占比）。',

    // 风险控制参数
    'STOP_LOSS_PERCENT': '止损百分比（如0.08表示8%，相对于保证金）。当亏损达到此百分比时自动平仓止损，限制单笔交易的最大亏损。值越小止损更严格，单笔损失更小但可能被正常波动触发。值越大允许更大的回撤，但单笔损失可能较大。建议：保守策略10-15%，平衡策略8-10%，激进策略5-8%。注意：止损应该小于止盈，建议盈亏比至少1:1.5。系统会结合最小价格变动保护，取更宽松的一个。',
    'TAKE_PROFIT_PERCENT': '止盈百分比（如0.15表示15%，相对于保证金）。当盈利达到此百分比时自动平仓止盈，锁定利润。值越大目标利润更高，但可能错过及时止盈的机会，持仓时间更长。值越小能更快锁定利润，但可能错过更大的趋势。建议：保守策略20-30%，平衡策略15-20%，激进策略10-15%。注意：应该大于止损，建议盈亏比至少1:1.5。系统会结合最小价格变动保护，取更宽松的一个。',
    'MIN_STOP_LOSS_PRICE_PCT': '最小止损价格变动百分比（存储为0~1，前端输入按%显示，支持小数，如1.5%）。用于防止止损过紧：即使基于保证金的止损更紧，也会使用至少该百分比的价格变动。建议：1.5%-3%。',
    'MIN_TAKE_PROFIT_PRICE_PCT': '最小止盈价格变动百分比（存储为0~1，前端输入按%显示，支持小数，如2.5%）。用于防止止盈过紧：即使基于保证金的止盈更紧，也会使用至少该百分比的价格变动。建议：2%-4%。',

    // 策略参数
    'LEVERAGE': '交易杠杆倍数。放大资金利用率，同时放大收益和风险。杠杆越高，相同仓位下需要的保证金越少，但风险越大。建议：保守策略5-10倍，平衡策略10倍，激进策略10-15倍。注意：高杠杆会增加爆仓风险，请谨慎使用。',
    'USE_TRAILING_STOP': '是否启用移动止损（true/false）。启用后，当盈利达到激活阈值时，止损会自动跟踪价格，保护利润。适合趋势行情，可以捕捉更大的利润空间。建议：平衡和激进策略启用，保守策略可关闭。',
    'SMART_ENTRY_ENABLED': '智能入场开关（true/false）。开启时会进行“限价回调 + 追价 +（趋势强时）市价兜底”，以减少错过；关闭时回归“纯限价单模式”：只下一次限价单，未在确认时间内成交则撤单跳过，更适合低频波段与控频。',
    'AUTO_TRADE_ONLY_TRENDING': '自动交易仅在市场状态=trending时执行（ranging/unknown只生成推荐，不自动下单）。开启能显著降低震荡扫损，但也会减少出单；如果你发现“几乎不下单”，可先关闭。',
    'AUTO_TRADE_ALLOW_4H_NEUTRAL': '是否允许4H趋势=neutral时自动交易。关闭可减少震荡扫损；开启会显著增加出单（但需要配合更严格的信号门槛/控频）。',
    'LIMIT_ORDER_OFFSET_PCT': '限价入场偏移（%）。BUY 会挂在当前价下方回调位置，SELL 会挂在当前价上方反弹位置。值越小越贴近当前价，更容易成交（但可能更“追价”）；值越大更保守，但更容易出现“挂单NEW→超时撤单”。建议：0.05%-0.20%。',
    'ENTRY_CONFIRM_TIMEOUT_SEC': '下单后等待成交的确认超时（秒）。在“纯限价模式”下，超时未成交会撤单并跳过；在“智能入场”下则进入后续追价/兜底流程。建议：60-180秒。',
    'ENTRY_CHASE_MAX_STEPS': '智能入场最大追价步数。步数越多越不容易错过，但也更接近追价；建议 2-4 步。',
    'ENTRY_STEP_WAIT_SEC': '智能入场每一步等待成交时间（秒）。过短会频繁撤改单，过长会错过行情；建议 15-25 秒。',
    'ENTRY_MARKET_FALLBACK_AFTER_SEC': '趋势强时市价兜底延迟（秒）。用于减少错过（在追价上限内才会触发），建议 45-90 秒。',
    'ENTRY_MAX_DRIFT_PCT_TRENDING': '趋势强时最大追价偏离（%）。例如 0.3 表示 0.3%。越小越保守、越不追价；建议 0.2%-0.6%。',
    'ENTRY_MAX_DRIFT_PCT_RANGING': '震荡/弱趋势最大追价偏离（%）。例如 0.15 表示 0.15%。越小越保守；建议 0.1%-0.3%。',
    'TRAILING_STOP_ACTIVATION': '移动止损激活阈值（百分比，如0.01表示1%）。当盈利达到此百分比时，移动止损开始跟踪价格，将止损移至成本价（保本）。值越小激活越早，更早保护利润但可能过早退出。值越大激活越晚，给价格更多波动空间。建议：1-2%。',
    'TRAILING_STOP_PROTECT': '移动止损保护利润（百分比，如0.01表示1%）。当价格从最高点回撤达到此百分比时，触发止损平仓，锁定利润。值越小保护更严格，能锁定更多利润但可能过早退出。值越大允许更大回撤，可能捕捉更大趋势但利润可能回吐。建议：1-2%。',

    // API配置
    'BINANCE_API_KEY': '币安API密钥。用于访问币安账户的凭证，需要启用"合约交易"权限。请妥善保管，不要泄露。',
    'BINANCE_API_SECRET': '币安API密钥。与API Key配对使用，用于签名验证。请妥善保管，不要泄露。',
    'USE_TESTNET': '是否使用币安测试网（true/false）。true表示使用测试网（模拟交易，无真实资金），false表示使用生产网（真实交易）。建议：测试时使用true，正式交易使用false。'
  }
  return details[key] || '暂无详细说明，请参考配置说明文档'
}

export default ConfigPanel
