import { useState, type CSSProperties } from 'react'
import { Alert, Button, Select, Space, Spin, Table, Tag, Tooltip } from 'antd'
import {
  type CampaignComparison, type CampaignListItem, type MetricDeltaPair,
  type MetricDiff, type ModelConfig,
} from '../api'
import { shortDateTime } from '../utils/date'
import { colors, statusColors } from '../tokens'

const TREND_META: Record<string, { label: string; color: string }> = {
  improving: { label: '改善', color: 'green' },
  stable: { label: '平稳', color: 'blue' },
  regressing: { label: '退化', color: 'red' },
}

const EVOLUTION_META: Record<string, { label: string; color: string }> = {
  new: { label: '新增', color: 'red' },
  persisting: { label: '持续', color: 'orange' },
  resolved: { label: '消解', color: 'green' },
}

const TRACKING_META: Record<string, { label: string; color: string }> = {
  addressed: { label: '已落实', color: 'green' },
  partial: { label: '部分落实', color: 'orange' },
  unaddressed: { label: '未落实', color: 'default' },
  new: { label: '新增', color: 'blue' },
}

type MetricKey = 'pass_rate' | 'availability' | 'avg_latency_ms'

const fmtPct = (v: number) => `${(v * 100).toFixed(1)}%`
const signed = (d: number, body: string) => `${d > 0 ? '+' : ''}${body}`

/** Single metric meta table: label, formatting and which direction is good. */
const METRICS: {
  key: MetricKey
  label: string
  goodDirection: 'up' | 'down'
  fmt: (v: number) => string
  fmtDelta: (d: number) => string
}[] = [
  { key: 'pass_rate', label: '通过率', goodDirection: 'up', fmt: fmtPct, fmtDelta: (d) => signed(d, `${(d * 100).toFixed(1)}pp`) },
  { key: 'availability', label: '可用性', goodDirection: 'up', fmt: fmtPct, fmtDelta: (d) => signed(d, `${(d * 100).toFixed(1)}pp`) },
  { key: 'avg_latency_ms', label: '平均时延', goodDirection: 'down', fmt: (v) => `${Math.round(v)}ms`, fmtDelta: (d) => signed(d, `${Math.round(d * 10) / 10}ms`) },
]

const boxStyle: CSSProperties = {
  border: `1px solid ${colors.border}`, borderRadius: 8,
  padding: '12px 14px', marginBottom: 16,
}

interface Props {
  comparison: CampaignComparison | null
  /** 活动已终态（按钮门控之一） */
  terminal: boolean
  /** 当前活动智能分析已 completed（对比前提） */
  analysisCompleted: boolean
  targetId: string
  currentCampaignId: string
  campaigns: CampaignListItem[]
  scenarioNames: Record<string, string>
  modelConfigs: ModelConfig[]
  onGenerate: (baselineCampaignId?: string) => Promise<void>
}

export default function PeriodComparisonSection({
  comparison, terminal, analysisCompleted, targetId, currentCampaignId,
  campaigns, scenarioNames, modelConfigs, onGenerate,
}: Props) {
  const [busy, setBusy] = useState(false)
  const [baselineChoice, setBaselineChoice] = useState<string | undefined>(undefined)

  const generate = async (baselineCampaignId?: string) => {
    setBusy(true)
    try {
      await onGenerate(baselineCampaignId)
    } finally {
      setBusy(false)
    }
  }

  const baselineCandidates = campaigns
    .filter((c) => c.target_id === targetId
      && c.id !== currentCampaignId
      && c.completed_at != null
      && !(c.status === 'planned' || c.status === 'running'))
    .slice()
    .sort((a, b) => (b.completed_at ?? '').localeCompare(a.completed_at ?? ''))

  const button = (label: string, baselineCampaignId?: string, requireBaseline = false) => (
    <Tooltip title={
      !terminal ? '活动完成后可生成'
        : !analysisCompleted ? '请先生成智能分析'
          : requireBaseline && !baselineCampaignId ? '请先选择基线活动'
            : undefined
    }>
      <Button
        size="small" type="primary" ghost
        loading={busy}
        disabled={!terminal || !analysisCompleted || (requireBaseline && !baselineCampaignId)}
        onClick={() => void generate(baselineCampaignId)}
      >
        {label}
      </Button>
    </Tooltip>
  )

  const metricDiffTable = (diff: MetricDiff) => {
    const rows = [
      { key: 'overall', name: '整窗（总体）', ...diff.overall },
      ...diff.scenarios.map((s) => ({
        key: s.scenario_id,
        name: s.scenario_name || scenarioNames[s.scenario_id] || s.scenario_id.slice(0, 8),
        pass_rate: s.pass_rate, availability: s.availability, avg_latency_ms: s.avg_latency_ms,
      })),
    ]
    const renderPair = (metric: typeof METRICS[number]) => (_: unknown, r: typeof rows[number]) => {
      const pair: MetricDeltaPair = r[metric.key]
      const good = metric.goodDirection === 'down' ? (pair.delta ?? 0) < 0 : (pair.delta ?? 0) > 0
      const deltaColor = pair.delta == null || pair.delta === 0
        ? colors.textMuted
        : good ? statusColors.completed : statusColors.failed
      return (
        <Space size={4}>
          <span style={{ color: colors.textMuted }}>
            {pair.baseline == null ? '—' : metric.fmt(pair.baseline)}
          </span>
          <span style={{ color: colors.textMuted }}>→</span>
          <span>{pair.current == null ? '—' : metric.fmt(pair.current)}</span>
          <span style={{ color: deltaColor, fontWeight: 500 }}>
            {pair.delta == null ? '—' : metric.fmtDelta(pair.delta)}
          </span>
        </Space>
      )
    }
    return (
      <Table
        rowKey="key"
        size="small"
        dataSource={rows}
        pagination={false}
        columns={[
          { title: '维度', dataIndex: 'name', key: 'name' },
          ...METRICS.map((m) => ({ title: m.label, key: m.key, render: renderPair(m) })),
        ]}
        style={{ marginBottom: 12 }}
      />
    )
  }

  const status = comparison?.status ?? 'none'
  if (status === 'generating') {
    return (
      <div style={boxStyle}>
        <Spin size="small" />
        <span style={{ marginLeft: 10, color: colors.textSecondary }}>
          正在生成周期对比叙述，通常需要几十秒…
        </span>
      </div>
    )
  }
  if (status === 'failed') {
    return (
      <div style={{ marginBottom: 16 }}>
        <Alert
          type="error" showIcon message="周期对比生成失败"
          description={comparison?.comparison?.error || '未知错误'}
          action={button('重试', comparison?.comparison?.baseline_campaign_id)}
        />
      </div>
    )
  }
  const entry = comparison?.comparison ?? null
  if (!entry || !entry.result) {
    const autoBaseline = comparison?.auto_baseline ?? null
    return (
      <div style={{ ...boxStyle, background: colors.bgSubtle }}>
        <div style={{ color: colors.textSecondary, marginBottom: 8 }}>
          {autoBaseline
            ? <>已找到自动基线「{autoBaseline.name}」（{shortDateTime(autoBaseline.completed_at)}），可生成对比叙述。</>
            : '未找到自动基线（需同计划、正式线、更早完成且已有智能分析的历史活动）。可手动选择基线。'}
        </div>
        <Space size={12} wrap>
          {autoBaseline
            ? button('生成对比')
            : (
              <>
                <Select
                  size="small"
                  style={{ minWidth: 260 }}
                  placeholder="选择基线活动"
                  value={baselineChoice}
                  onChange={(v) => setBaselineChoice(v)}
                  options={baselineCandidates.map((c) => ({
                    label: `${c.name}（完成于 ${shortDateTime(c.completed_at)}）`,
                    value: c.id,
                  }))}
                  notFoundContent="没有可选的历史活动"
                />
                {button('生成对比', baselineChoice, true)}
              </>
            )}
          {!analysisCompleted && (
            <span style={{ fontSize: 12, color: colors.warning }}>请先完成智能分析后再生成对比</span>
          )}
        </Space>
        {comparison?.metric_diff && metricDiffTable(comparison.metric_diff)}
      </div>
    )
  }
  const result = entry.result
  const baseline = entry.baseline
  const trendMeta = TREND_META[result.trend] ?? TREND_META.stable
  const modelName = entry.model_config_id
    ? modelConfigs.find((m) => m.id === entry.model_config_id)?.name ?? entry.model_config_id.slice(0, 8)
    : null
  return (
    <div style={boxStyle}>
      <div style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        fontSize: 12, color: colors.textSecondary, marginBottom: 10,
      }}>
        <span>
          基线「{baseline?.name ?? entry.baseline_campaign_id.slice(0, 8)}」
          {baseline?.completed_at && <>（完成于 {shortDateTime(baseline.completed_at)}）</>}
          {' · '}模型 {modelName ?? '未知'}
          {entry.updated_at && <> · 生成于 {shortDateTime(entry.updated_at)}</>}
        </span>
        {button('重新生成', entry.baseline_campaign_id)}
      </div>
      <div style={{
        background: '#e6f4ff', border: '1px solid #91caff', borderRadius: 8,
        padding: '10px 14px', marginBottom: 12,
      }}>
        <Space size={8} align="start">
          <Tag color={trendMeta.color} style={{ margin: 0 }}>{trendMeta.label}</Tag>
          <span><b>总体趋势：</b>{result.summary}</span>
        </Space>
      </div>
      {comparison?.metric_diff && metricDiffTable(comparison.metric_diff)}
      {result.problem_evolution.length > 0 && (
        <div style={{ marginBottom: 12 }}>
          <div style={{ fontWeight: 500, marginBottom: 8 }}>问题演变</div>
          <Space direction="vertical" size={8} style={{ width: '100%' }}>
            {result.problem_evolution.map((p, i) => {
              const meta = EVOLUTION_META[p.status] ?? EVOLUTION_META.persisting
              return (
                <div key={i} style={{ border: `1px solid ${colors.border}`, borderRadius: 8, padding: '8px 12px' }}>
                  <Space size={8} wrap>
                    <Tag color={meta.color} style={{ margin: 0 }}>{meta.label}</Tag>
                    <b>{p.title}</b>
                    {p.scenario_ids.map((sid) => (
                      <Tag key={sid} style={{ margin: 0 }}>{scenarioNames[sid] ?? sid.slice(0, 8)}</Tag>
                    ))}
                  </Space>
                  <div style={{ color: colors.textSecondary, marginTop: 6 }}>{p.detail}</div>
                </div>
              )
            })}
          </Space>
        </div>
      )}
      {result.suggestion_tracking.length > 0 && (
        <div>
          <div style={{ fontWeight: 500, marginBottom: 8 }}>建议落实情况</div>
          <Space direction="vertical" size={6} style={{ width: '100%' }}>
            {result.suggestion_tracking.map((s, i) => {
              const meta = TRACKING_META[s.status] ?? TRACKING_META.unaddressed
              return (
                <div key={i}>
                  <Space size={8} wrap>
                    <Tag color={meta.color} style={{ margin: 0 }}>{meta.label}</Tag>
                    <span>{s.text}</span>
                  </Space>
                  {s.note && (
                    <div style={{ color: colors.textSecondary, fontSize: 12, margin: '2px 0 0 22px' }}>{s.note}</div>
                  )}
                </div>
              )
            })}
          </Space>
        </div>
      )}
    </div>
  )
}
