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

const ConfigPanel = () => {
  const [configs, setConfigs] = useState({})
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [message, setMessage] = useState('')
  
  // 预设方案配置
  const presets = {
    conservative: {
      name: '保守配置',
      desc: '适合新手，风险较低，交易频率适中',
      configs: {
        SCAN_INTERVAL: 3600,
        MIN_CHANGE_PERCENT: 2.0,
        MIN_SIGNAL_STRENGTH: 5,
        TOP_N_SYMBOLS: 10,
        MIN_VOLATILITY: 0.02
      }
    },
    balanced: {
      name: '平衡配置',
      desc: '推荐使用，平衡频率和质量',
      configs: {
        SCAN_INTERVAL: 600,
        MIN_CHANGE_PERCENT: 1.5,
        MIN_SIGNAL_STRENGTH: 4,
        TOP_N_SYMBOLS: 12,
        MIN_VOLATILITY: 0.018
      }
    },
    aggressive: {
      name: '激进高频',
      desc: '晚间波动大时使用，交易频率高',
      configs: {
        SCAN_INTERVAL: 300,
        MIN_CHANGE_PERCENT: 1.0,
        MIN_SIGNAL_STRENGTH: 3,
        TOP_N_SYMBOLS: 20,
        MIN_VOLATILITY: 0.015
      }
    }
  }

  useEffect(() => {
    loadConfigs()
  }, [])

  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()
    } catch (error) {
      const errorMsg = error.message || '更新失败'
      setMessage('更新失败: ' + errorMsg)
      console.error('Config update error:', error)
    } finally {
      setSaving(false)
    }
  }

  // 检测当前配置匹配哪个预设方案
  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')) {
          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) return null
        return {
          key,
          value: key.includes('PERCENT') ? 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">
          <h2>交易配置</h2>
          <Link to="/config/guide" className="guide-link">📖 配置说明</Link>
        </div>
        <div className="config-info">
          <p>修改配置后，交易系统将在下次扫描时自动使用新配置</p>
        </div>
        
        {/* 预设方案快速切换 */}
        <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-buttons">
            {Object.entries(presets).map(([key, preset]) => (
              <button
                key={key}
                className={`preset-btn ${currentPreset === key ? 'active' : ''}`}
                onClick={() => applyPreset(key)}
                disabled={saving}
                title={preset.desc}
              >
                <div className="preset-name">
                  {preset.name}
                  {currentPreset === key && <span className="active-indicator">✓</span>}
                </div>
                <div className="preset-desc">{preset.desc}</div>
              </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]) => config.category === category)
              .map(([key, config]) => (
                <ConfigItem
                  key={key}
                  label={key}
                  config={config}
                  onUpdate={(value) => handleUpdate(key, value, config.type, config.category)}
                  disabled={saving}
                />
              ))}
          </div>
        </section>
      ))}
    </div>
  )
}

const ConfigItem = ({ label, config, onUpdate, disabled }) => {
  const [value, setValue] = useState(config.value)
  const [localValue, setLocalValue] = useState(config.value)
  const [isEditing, setIsEditing] = useState(false)
  const [showDetail, setShowDetail] = useState(false)

  useEffect(() => {
    setValue(config.value)
    setLocalValue(config.value)
  }, [config.value])

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

  const handleSave = () => {
    setIsEditing(false)
    if (localValue !== value) {
      // 值发生变化，保存
      let finalValue = localValue
      if (config.type === 'number') {
        finalValue = parseFloat(localValue) || 0
        // 百分比配置需要转换
        if (label.includes('PERCENT')) {
          finalValue = finalValue
        }
      } else if (config.type === 'boolean') {
        finalValue = localValue === 'true' || localValue === true
      }
      onUpdate(finalValue)
    }
  }

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

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

  const displayValue = config.type === 'number' && label.includes('PERCENT') 
    ? (localValue * 100).toFixed(2) 
    : 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={config.type === 'number' ? 'number' : 'text'}
          value={label.includes('PERCENT') ? displayValue : localValue}
          onChange={(e) => {
            const newValue = config.type === 'number' && label.includes('PERCENT')
              ? parseFloat(e.target.value) / 100
              : e.target.value
            handleChange(newValue)
          }}
          onBlur={handleBlur}
          onKeyPress={handleKeyPress}
          disabled={disabled}
          step={config.type === 'number' ? '0.01' : undefined}
          className={isEditing ? 'editing' : ''}
        />
        {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': '扫描间隔（秒）。系统每隔多长时间扫描一次市场寻找交易机会。值越小扫描越频繁，能更快捕捉波动，但会增加API请求和系统负载。建议：保守策略3600秒(1小时)，平衡策略600秒(10分钟)，激进策略300秒(5分钟)。晚间波动大时可降低到300-600秒。',
    'MIN_CHANGE_PERCENT': '最小涨跌幅阈值（%）。只有24小时涨跌幅达到此值的交易对才会被考虑交易。值越小捕捉机会越多，但可能包含噪音和假信号。值越大只捕捉大幅波动，信号质量更高但机会更少。建议：保守策略2.0-3.0%，平衡策略1.5-2.0%，激进策略1.0-1.5%。',
    'MIN_SIGNAL_STRENGTH': '最小信号强度（0-10）。技术指标综合评分，只有达到此强度的信号才会执行交易。值越小交易机会越多，但信号质量可能下降，胜率降低。值越大只执行高质量信号，胜率更高但机会更少。建议：保守策略5-7，平衡策略4-5，激进策略3-4。',
    'TOP_N_SYMBOLS': '每次扫描后处理的交易对数量。从符合条件的交易对中选择涨跌幅最大的前N个进行详细分析。值越大机会越多，但计算量增加，API请求增多。建议：保守策略8-10个，平衡策略12-15个，激进策略15-20个。',
    '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.05表示5%）。单笔交易允许的最大仓位大小。值越大单笔金额越大，潜在收益和风险都增加。注意：币安要求最小名义价值5 USDT，如果账户余额较小，系统会自动调整。建议：保守策略3-5%，平衡策略5-7%，激进策略7-10%。',
    'MAX_TOTAL_POSITION_PERCENT': '总仓位上限（账户余额的百分比，如0.30表示30%）。所有持仓的总价值不能超过账户余额的百分比，防止过度交易和风险集中。值越大可以同时持有更多仓位，但风险集中度增加。建议：保守策略20-30%，平衡策略30-40%，激进策略40-50%。',
    'MIN_POSITION_PERCENT': '单笔最小仓位（账户余额的百分比，如0.01表示1%）。单笔交易允许的最小仓位大小，避免交易过小的仓位，减少手续费影响。建议：1-2%。',
    
    // 风险控制参数
    'STOP_LOSS_PERCENT': '止损百分比（如0.03表示3%）。当亏损达到此百分比时自动平仓止损，限制单笔交易的最大亏损。值越小止损更严格，单笔损失更小但可能被正常波动触发。值越大允许更大的回撤，但单笔损失可能较大。建议：保守策略3-5%，平衡策略2-3%，激进策略2-3%。注意：止损应该小于止盈，建议盈亏比至少1:1.5。',
    'TAKE_PROFIT_PERCENT': '止盈百分比（如0.05表示5%）。当盈利达到此百分比时自动平仓止盈，锁定利润。值越大目标利润更高，但可能错过及时止盈的机会，持仓时间更长。值越小能更快锁定利润，但可能错过更大的趋势。建议：保守策略5-8%，平衡策略5-6%，激进策略3-5%。注意：应该大于止损，建议盈亏比至少1:1.5。',
    
    // 策略参数
    'LEVERAGE': '交易杠杆倍数。放大资金利用率，同时放大收益和风险。杠杆越高，相同仓位下需要的保证金越少，但风险越大。建议：保守策略5-10倍，平衡策略10倍，激进策略10-15倍。注意：高杠杆会增加爆仓风险，请谨慎使用。',
    'USE_TRAILING_STOP': '是否启用移动止损（true/false）。启用后，当盈利达到激活阈值时，止损会自动跟踪价格，保护利润。适合趋势行情，可以捕捉更大的利润空间。建议：平衡和激进策略启用，保守策略可关闭。',
    'TRAILING_STOP_ACTIVATION': '移动止损激活阈值（百分比，如0.01表示1%）。当盈利达到此百分比时，移动止损开始跟踪价格，将止损移至成本价（保本）。值越小激活越早，更早保护利润但可能过早退出。值越大激活越晚，给价格更多波动空间。建议：1-2%。',
    'TRAILING_STOP_PROTECT': '移动止损保护利润（百分比，如0.01表示1%）。当价格从最高点回撤达到此百分比时，触发止损平仓，锁定利润。值越小保护更严格，能锁定更多利润但可能过早退出。值越大允许更大回撤，可能捕捉更大趋势但利润可能回吐。建议：1-2%。',
    'USE_UNICORN_WEBSOCKET': '是否使用高性能Unicorn WebSocket API（true/false）。启用后使用unicorn-binance-websocket-api获取实时数据，效率更高，减少API请求频率限制。建议：启用（true）。',
    
    // 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
