import { useMemo, useState } from 'react'
import { Empty, Input, Pagination, Progress, Segmented, Skeleton, Tag, Tooltip } from 'antd'
import { FileTextOutlined, SearchOutlined } from '@ant-design/icons'
import dayjs from 'dayjs'
import type { Run, Scenario, Target } from '../api'
import type { RunProgress } from '../hooks/useRunSession'
import { colors, statusColors, statusLabels, triggerColors, triggerLabels } from '../tokens'
import { elapsedStr, shortDateTime, toDate } from '../utils/date'

const PAGE_SIZE = 10

interface RunListProps {
  runs: Run[]
  loading: boolean
  targets: Target[]
  scenarios: Scenario[]
  selectedId?: string
  onSelect: (r: Run) => void
  onOpenReport?: (runId: string) => void
  liveRunId?: string
  liveProgress?: RunProgress | null
}

type StatusFilter = 'all' | 'running' | 'completed' | 'failed'
type TimeFilter = 'today' | '1d' | '7d' | '30d' | null

const TIME_OPTIONS: { label: string; value: TimeFilter }[] = [
  { label: '当天', value: 'today' },
  { label: '1天',  value: '1d'   },
  { label: '7天',  value: '7d'   },
  { label: '30天', value: '30d'  },
]

function getDateRange(tf: TimeFilter): [number, number] | null {
  if (!tf) return null
  const now = dayjs()
  if (tf === 'today') return [now.startOf('day').valueOf(), now.endOf('day').valueOf()]
  if (tf === '1d')    return [now.subtract(1, 'day').startOf('day').valueOf(), now.endOf('day').valueOf()]
  if (tf === '7d')    return [now.subtract(6, 'day').startOf('day').valueOf(), now.endOf('day').valueOf()]
  if (tf === '30d')   return [now.subtract(29, 'day').startOf('day').valueOf(), now.endOf('day').valueOf()]
  return null
}

export default function RunList({
  runs, loading, targets, scenarios, selectedId, onSelect, onOpenReport,
  liveRunId, liveProgress,
}: RunListProps) {
  const [filter, setFilter] = useState<StatusFilter>('all')
  const [keyword, setKeyword] = useState('')
  const [timeFilter, setTimeFilter] = useState<TimeFilter>('today')
  const [page, setPage] = useState(1)

  const targetName = useMemo(
    () => Object.fromEntries(targets.map((t) => [t.id, t.name])),
    [targets],
  )
  const scenarioName = useMemo(
    () => Object.fromEntries(scenarios.map((s) => [s.id, s.name])),
    [scenarios],
  )

  const filtered = useMemo(() => {
    const kw = keyword.trim().toLowerCase()
    const range = getDateRange(timeFilter)
    return runs.filter((r) => {
      if (filter === 'running' && r.status !== 'running' && r.status !== 'pending') return false
      if (filter === 'completed' && r.status !== 'completed') return false
      if (filter === 'failed' && r.status !== 'failed') return false
      if (range) {
        const t = r.started_at ? toDate(r.started_at).getTime() : null
        if (t != null && (t < range[0] || t > range[1])) return false
      }
      if (!kw) return true
      const tn = (targetName[r.target_id] ?? '').toLowerCase()
      const sn = (scenarioName[r.scenario_id] ?? '').toLowerCase()
      return r.id.toLowerCase().includes(kw) || tn.includes(kw) || sn.includes(kw)
    })
  }, [runs, filter, keyword, timeFilter, targetName, scenarioName])

  const total = filtered.length
  const pageItems = useMemo(
    () => filtered.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE),
    [filtered, page],
  )
  const resetPage = () => setPage(1)

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', minHeight: 0 }}>

      {/* ── 筛选区 ── */}
      <div style={{
        padding: '8px 10px',
        borderBottom: `1px solid ${colors.border}`,
        background: colors.bgSubtle,
        flexShrink: 0,
        display: 'flex',
        flexDirection: 'column',
        gap: 6,
      }}>
        {/* 第一行：搜索框 */}
        <Input
          size="small"
          allowClear
          placeholder="搜索场景 / 对象 / ID"
          prefix={<SearchOutlined style={{ color: colors.textMuted }} />}
          value={keyword}
          onChange={(e) => { setKeyword(e.target.value); resetPage() }}
        />

        {/* 第二行：状态分段 + 时间快捷标签 + 总数 */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          <Segmented
            size="small"
            value={filter}
            onChange={(v) => { setFilter(v as StatusFilter); resetPage() }}
            options={[
              { label: '全部', value: 'all' },
              { label: '进行中', value: 'running' },
              { label: '成功', value: 'completed' },
              { label: '失败', value: 'failed' },
            ]}
          />
          <div style={{ display: 'flex', gap: 4, marginLeft: 'auto' }}>
            {TIME_OPTIONS.map(({ label, value }) => {
              const active = timeFilter === value
              return (
                <span
                  key={value}
                  onClick={() => { setTimeFilter(active ? null : value); resetPage() }}
                  style={{
                    fontSize: 11,
                    padding: '1px 8px',
                    borderRadius: 10,
                    cursor: 'pointer',
                    userSelect: 'none',
                    background: active ? colors.primary : '#e8e8e8',
                    border: `1px solid ${active ? colors.primary : '#bfbfbf'}`,
                    color: active ? '#fff' : '#4b5563',
                    lineHeight: '18px',
                    display: 'inline-block',
                    transition: 'all 0.15s',
                    fontWeight: active ? 600 : 400,
                  }}
                >
                  {label}
                </span>
              )
            })}
          </div>
          <span style={{ fontSize: 11, color: colors.textMuted, flexShrink: 0 }}>
            {total}条
          </span>
        </div>
      </div>

      {/* ── 列表主体 ── */}
      <div style={{ flex: 1, overflowY: 'auto', minHeight: 0 }}>
        {loading ? (
          <div style={{ padding: '12px 10px' }}>
            {[0, 1, 2].map((i) => (
              <Skeleton key={i} active paragraph={{ rows: 2 }} style={{ marginBottom: 10 }} />
            ))}
          </div>
        ) : total === 0 ? (
          <Empty
            image={Empty.PRESENTED_IMAGE_SIMPLE}
            description={runs.length === 0 ? '尚未启动过评测' : '无匹配记录'}
            style={{ marginTop: 60 }}
          />
        ) : (
          pageItems.map((r) => (
            <RunRow
              key={r.id}
              r={r}
              selected={r.id === selectedId}
              targetName={targetName[r.target_id] ?? r.target_id}
              scenarioName={scenarioName[r.scenario_id] ?? r.scenario_id}
              onSelect={onSelect}
              onOpenReport={onOpenReport}
              liveProgress={r.id === liveRunId ? (liveProgress ?? null) : null}
            />
          ))
        )}
      </div>

      {/* ── 分页栏 ── */}
      <div style={{
        borderTop: `1px solid ${colors.border}`,
        padding: '5px 10px',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        flexShrink: 0,
        minHeight: 38,
        background: colors.bgSubtle,
      }}>
        {total > 0 && (
          <Pagination
            size="small"
            current={page}
            pageSize={PAGE_SIZE}
            total={total}
            onChange={setPage}
            showSizeChanger={false}
            showQuickJumper={total > PAGE_SIZE * 4}
            hideOnSinglePage={false}
          />
        )}
      </div>
    </div>
  )
}

// ── RunRow ─────────────────────────────────────────────────────────────────────

interface RunRowProps {
  r: Run
  selected: boolean
  targetName: string
  scenarioName: string
  onSelect: (r: Run) => void
  onOpenReport?: (runId: string) => void
  liveProgress: RunProgress | null
}

function RunRow({ r, selected, targetName, scenarioName, onSelect, onOpenReport, liveProgress }: RunRowProps) {
  const { status } = r
  const dotColor = statusColors[status] ?? colors.textMuted
  const isActive = status === 'running' || status === 'pending'

  const bar = (() => {
    if (status === 'completed') {
      const passRate = r.summary?.pass_rate
      if (passRate != null) {
        const pct = Math.round(passRate * 100)
        const color = pct >= 80 ? statusColors.completed : pct >= 50 ? '#faad14' : statusColors.failed
        return { pct, color, label: `${pct}%`, active: false }
      }
      return { pct: 100, color: colors.textMuted, label: '完成', active: false }
    }
    if (isActive) {
      if (liveProgress && liveProgress.total > 0) {
        const pct = Math.round((liveProgress.done / liveProgress.total) * 100)
        return { pct, color: statusColors.running, label: `${liveProgress.done}/${liveProgress.total}`, active: true }
      }
      return { pct: 0, color: statusColors.running, label: '等待中…', active: true }
    }
    return { pct: 0, color: statusColors.failed, label: '0%', active: false }
  })()

  return (
    <div
      className="run-row"
      onClick={() => onSelect(r)}
      style={{
        padding: '9px 12px 8px 14px',
        borderBottom: `1px solid ${colors.border}`,
        cursor: 'pointer',
        background: selected ? '#e6f4ff55' : undefined,
        borderLeft: selected ? `3px solid ${colors.primary}` : `3px solid transparent`,
      }}
    >
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 3 }}>
        {isActive
          ? <span className="pulse-dot" style={{ background: dotColor }} />
          : <span style={{ width: 8, height: 8, borderRadius: '50%', background: dotColor, flexShrink: 0, display: 'inline-block' }} />}
        <Tooltip title={`${scenarioName} · ${targetName}`}>
          <div style={{
            flex: 1, minWidth: 0,
            fontSize: 13, fontWeight: 500, color: colors.text,
            overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
          }}>
            {scenarioName}
            <span style={{ color: colors.textMuted, marginLeft: 4 }}>· {targetName}</span>
          </div>
        </Tooltip>
        <span style={{ fontSize: 11, color: dotColor, fontWeight: 500, flexShrink: 0 }}>
          {statusLabels[status] ?? status}
        </span>
      </div>

      <div style={{
        display: 'flex', alignItems: 'center', gap: 6,
        fontSize: 11, color: colors.textMuted, marginBottom: 5,
      }}>
        <Tooltip title={r.id}>
          <code style={{ fontFamily: 'ui-monospace, SFMono-Regular, monospace' }}>
            {r.id.slice(0, 8)}
          </code>
        </Tooltip>
        <span>·</span>
        <span>{shortDateTime(r.started_at)}</span>
        <span>·</span>
        <span>{elapsedStr(r.started_at, r.completed_at)}</span>
        {r.scenario_version != null && (
          <Tooltip title="场景考纲版本">
            <Tag style={{ marginLeft: 2, marginRight: 0, fontSize: 10, lineHeight: '16px', padding: '0 4px' }}>
              v{r.scenario_version}
            </Tag>
          </Tooltip>
        )}
        {r.triggered_by && (
          <Tag
            color={triggerColors[r.triggered_by] ?? 'default'}
            style={{ marginLeft: 2, marginRight: 0, fontSize: 10, lineHeight: '16px', padding: '0 4px' }}
          >
            {triggerLabels[r.triggered_by] ?? r.triggered_by}
          </Tag>
        )}
        {onOpenReport && status === 'completed' && (
          <Tooltip title="查看报告">
            <FileTextOutlined
              onClick={(e) => { e.stopPropagation(); onOpenReport(r.id) }}
              style={{ marginLeft: 'auto', color: colors.textMuted, cursor: 'pointer' }}
            />
          </Tooltip>
        )}
      </div>

      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        <span style={{
          fontSize: 11, color: bar.color, fontWeight: 600,
          minWidth: 48, flexShrink: 0, textAlign: 'right',
        }}>
          {bar.label}
        </span>
        <Progress
          percent={bar.pct}
          size="small"
          strokeColor={bar.color}
          showInfo={false}
          status={bar.active ? 'active' : 'normal'}
          style={{ flex: 1, margin: 0 }}
        />
      </div>
    </div>
  )
}
