import { useEffect, useState } from 'react'
import { Collapse, Empty, Space, Spin, Tag } from 'antd'
import ChatBubble from './ChatBubble'
import {
  explorationApi,
  type ExplorationMessage,
  type ExplorationSession,
  type ExplorationSummary,
} from '../api'
import { colors } from '../tokens'
import { shortDateTime } from '../utils/date'

const SESSION_STATUS: Record<string, { label: string; color: string }> = {
  running: { label: '进行中', color: 'processing' },
  completed: { label: '已完成', color: 'success' },
  failed: { label: '失败', color: 'error' },
  expired: { label: '已过期', color: 'default' },
}

const EMOTION_LABELS: Record<string, string> = {
  positive: '满意',
  neutral: '平静',
  confused: '困惑',
  frustrated: '沮丧',
}

const DIMENSION_LABELS: Record<string, string> = {
  attitude: '服务态度',
  professionalism: '专业度',
  hallucination: '幻觉',
}

const RATING_TAG: Record<string, { label: string; color: string }> = {
  poor: { label: '差', color: 'red' },
  acceptable: { label: '一般', color: 'orange' },
  good: { label: '优', color: 'green' },
}

function pct(rate: number | null): string {
  return rate == null ? '—' : `${(rate * 100).toFixed(1)}%`
}

function IssueList({ label, items, misled }: {
  label: string
  items: { issue: string; count: number }[]
  misled?: boolean
}) {
  if (items.length === 0) return null
  return (
    <div style={{ marginBottom: 10 }}>
      <div style={{ fontSize: 12, color: colors.textSecondary, marginBottom: 6 }}>{label}</div>
      <Space size={8} wrap>
        {items.map((item, i) => (
          <Tag key={i} color={misled ? 'orange' : 'red'}>
            {misled ? `（被误导）${item.issue}` : item.issue} ×{item.count}
          </Tag>
        ))}
      </Space>
    </div>
  )
}

function SessionDetail({ session, messages }: {
  session: ExplorationSession
  messages: ExplorationMessage[] | null
}) {
  const experience = session.experience
  return (
    <div>
      <div style={{ fontSize: 12, color: colors.textSecondary, marginBottom: 10 }}>
        目标：{session.goal}
        {session.created_at && <> · 开始于 {shortDateTime(session.created_at)}</>}
        {session.closed_at && <> · 结束于 {shortDateTime(session.closed_at)}</>}
      </div>

      {!messages && <Spin size="small" />}
      {messages && messages.length === 0 && (
        <Empty description="暂无对话记录" image={Empty.PRESENTED_IMAGE_SIMPLE} />
      )}
      {messages && messages.map((m) => (
        <ChatBubble
          key={m.id}
          role={m.role === 'user' ? 'user' : 'agent'}
          mirrored
          content={m.content}
          meta={m.role !== 'user' && m.latency_ms != null ? (
            <span style={{ color: colors.textMuted, fontSize: 11 }}>{m.latency_ms}ms</span>
          ) : undefined}
        />
      ))}

      {experience && (
        <div style={{
          marginTop: 8, border: `1px solid ${colors.border}`, borderRadius: 8,
          background: colors.bgSubtle, padding: '10px 12px', fontSize: 13, lineHeight: 1.8,
        }}>
          <div style={{ fontWeight: 500, marginBottom: 4 }}>体验记录</div>
          <Space size={8} wrap>
            {experience.goal_achieved
              ? <Tag color="success">目标达成</Tag>
              : <Tag color="error">目标未达成</Tag>}
            <Tag>{EMOTION_LABELS[experience.emotion] ?? experience.emotion}</Tag>
          </Space>
          {experience.blockers.length > 0 && (
            <div style={{ color: colors.textSecondary }}>障碍：{experience.blockers.join('；')}</div>
          )}
          {experience.misled.length > 0 && (
            <div style={{ color: colors.warning }}>被误导：{experience.misled.join('；')}</div>
          )}
          {experience.notes && (
            <div style={{ color: colors.textSecondary }}>备注：{experience.notes}</div>
          )}
        </div>
      )}
      {session.error && (
        <div style={{ marginTop: 8, fontSize: 12, color: colors.textMuted }}>会话异常：{session.error}</div>
      )}
    </div>
  )
}

export default function ExplorationSection({ campaignId, summary }: {
  campaignId: string
  summary: ExplorationSummary
}) {
  const [sessions, setSessions] = useState<ExplorationSession[] | null>(null)
  const [loading, setLoading] = useState(false)
  const [messageCache, setMessageCache] = useState<Record<string, ExplorationMessage[]>>({})

  useEffect(() => {
    let cancelled = false
    setLoading(true)
    explorationApi.listSessions(campaignId)
      .then((res) => { if (!cancelled) setSessions(res.data.sessions) })
      .catch(() => undefined) // 拦截器已弹错；避免未处理 rejection
      .finally(() => { if (!cancelled) setLoading(false) })
    return () => { cancelled = true }
  }, [campaignId])

  const onExpand = (keys: string | string[]) => {
    for (const key of Array.isArray(keys) ? keys : [keys]) {
      if (key in messageCache) continue
      void explorationApi.listMessages(key)
        .then((res) => { setMessageCache((prev) => ({ ...prev, [key]: res.data.messages })) })
        .catch(() => undefined) // 拦截器已弹错；收起再展开可重试
    }
  }

  const judge = summary.judge_review
  return (
    <div style={{
      border: `1px solid ${colors.border}`, borderRadius: 8,
      padding: '12px 14px', marginBottom: 16,
    }}>
      <div style={{ fontSize: 12, color: colors.textSecondary, marginBottom: 10 }}>
        探索会话 {summary.session_count} 个 · 有体验记录 {summary.sessions_with_experience} 个
        {' · '}目标达成率 {pct(summary.goal_achievement_rate)}（{summary.goal_achieved_count}/{summary.sessions_with_experience}）
      </div>

      <IssueList label="问题清单（体验记录）" items={summary.issues} />
      <IssueList label="被误导清单（体验记录）" items={summary.misled} misled />
      {summary.issues.length === 0 && summary.misled.length === 0 && (
        <div style={{ fontSize: 12, color: colors.textMuted, marginBottom: 10 }}>体验记录未报告问题</div>
      )}

      {judge && (
        <div style={{ marginBottom: 10 }}>
          <div style={{ fontSize: 12, color: colors.textSecondary, marginBottom: 6 }}>
            judge 复核（{judge.reviewed_sessions} 个会话抽样）
          </div>
          {judge.findings.length === 0
            ? <div style={{ fontSize: 13, color: colors.textSecondary }}>无复核发现</div>
            : (
              <Space direction="vertical" size={4} style={{ width: '100%' }}>
                {judge.findings.map((f, i) => (
                  <div key={i} style={{ fontSize: 13 }}>
                    <Tag color={RATING_TAG[f.rating]?.color ?? 'default'} style={{ margin: 0 }}>
                      {DIMENSION_LABELS[f.dimension] ?? f.dimension}
                      {' · '}
                      {RATING_TAG[f.rating]?.label ?? f.rating}
                    </Tag>
                    {' '}{f.comment}
                  </div>
                ))}
              </Space>
            )}
          {judge.summaries.map((s, i) => (
            <div key={i} style={{ fontSize: 13, color: colors.textSecondary, marginTop: 4 }}>
              复核结论：{s}
            </div>
          ))}
        </div>
      )}

      {loading && <Spin size="small" />}
      {!loading && sessions && sessions.length === 0 && (
        <Empty description="暂无探索会话" image={Empty.PRESENTED_IMAGE_SIMPLE} />
      )}
      {sessions && sessions.length > 0 && (
        <Collapse
          size="small"
          onChange={onExpand}
          items={sessions.map((s) => {
            const meta = SESSION_STATUS[s.status] ?? SESSION_STATUS.running
            const personaName = typeof s.persona?.name === 'string' ? s.persona.name : s.id.slice(0, 8)
            return {
              key: s.id,
              label: (
                <Space size={8} wrap>
                  <span style={{ fontWeight: 500 }}>{personaName}</span>
                  <Tag color={meta.color}>{meta.label}</Tag>
                  <Tag>{s.turn_count} 轮</Tag>
                  {s.experience?.goal_achieved != null && (
                    s.experience.goal_achieved
                      ? <Tag color="success">目标达成</Tag>
                      : <Tag color="error">目标未达成</Tag>
                  )}
                </Space>
              ),
              children: <SessionDetail session={s} messages={messageCache[s.id] ?? null} />,
            }
          })}
        />
      )}
    </div>
  )
}
