import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import type { IntelligentEval, IntelligentEvalReport } from '../../api'
import EvalReport from './EvalReport'

const downloadReportMarkdown = vi.fn()
const listMessages = vi.fn()

vi.mock('../../api', () => ({
  intelligentEvalsApi: {
    downloadReportMarkdown: (...args: unknown[]) => downloadReportMarkdown(...args),
    listMessages: (...args: unknown[]) => listMessages(...args),
  },
}))

function makeReport(overrides: Partial<IntelligentEvalReport> = {}): IntelligentEvalReport {
  return {
    summary: '整体服务态度良好，价保场景存在流程遗漏',
    scores: { overall: 4.2, dimensions: { 服务态度: 4.5, 专业度: 3.2 } },
    findings: [
      {
        issue: '价保流程未主动告知凭证',
        severity: 'high',
        dimension: '专业度',
        evidence: [{ session_id: 'sess-aaaaaaaa', turn_index: 2, user_said: '需要什么凭证', assistant_replied: '您好' }],
        suggestion: '补充 SOP 提示',
        related_sop: 'SOP-12',
      },
      {
        issue: '回复偏慢',
        severity: 'medium',
        dimension: '响应时效',
        evidence: [],
      },
    ],
    highlights: [{ description: '语气友好', dimension: '服务态度' }],
    priority_recommendations: ['优先整改价保流程'],
    ...overrides,
  }
}

function makeEval(overrides: Partial<IntelligentEval> = {}): IntelligentEval {
  return {
    id: 'eval-1',
    name: '24h 评估',
    target_id: 't-1',
    status: 'completed',
    goal: 'goal',
    seeds: {},
    intent: '',
    role_description: '',
    plan: null,
    plan_feedback: null,
    time_window_hours: 24,
    report: makeReport(),
    created_at: null,
    updated_at: null,
    started_at: null,
    completed_at: '2026-01-02T00:00:00Z',
    session_count: 1,
    completed_sessions: 1,
    sessions: [
      {
        id: 's-1',
        eval_id: 'eval-1',
        target_id: 't-1',
        persona: { name: '老客户' },
        goal: '完成退货',
        dimension: '售后',
        status: 'completed',
        verdict: null,
        turn_count: 5,
        created_at: '2026-01-01T08:10:00Z',
        closed_at: '2026-01-01T08:25:00Z',
      },
    ],
    ...overrides,
  }
}

beforeEach(() => {
  vi.clearAllMocks()
})

afterEach(() => {
  cleanup()
})

describe('EvalReport', () => {
  it('shows empty states when there is no report and no sessions', () => {
    render(<EvalReport ev={makeEval({ report: null, sessions: [] })} />)

    expect(screen.getByText('暂无报告')).toBeInTheDocument()
    expect(screen.getByText('暂无会话')).toBeInTheDocument()
  })

  it('renders summary cards, dimension scores, findings, highlights and recommendations', () => {
    render(<EvalReport ev={makeEval()} />)

    expect(screen.getByText('4.2')).toBeInTheDocument()
    expect(screen.getByText('问题发现（2）')).toBeInTheDocument()
    expect(screen.getAllByText('服务态度').length).toBeGreaterThanOrEqual(1)
    expect(screen.getByText('4.5')).toBeInTheDocument()
    expect(screen.getByText('3.2')).toBeInTheDocument()
    expect(screen.getByText('整体服务态度良好，价保场景存在流程遗漏')).toBeInTheDocument()
    expect(screen.getByText('价保流程未主动告知凭证')).toBeInTheDocument()
    expect(screen.getByText('回复偏慢')).toBeInTheDocument()
    expect(screen.getByText('语气友好')).toBeInTheDocument()
    expect(screen.getByText('优先整改价保流程')).toBeInTheDocument()
    expect(document.body.textContent).toContain('高 1 · 中 1 · 低 0')
  })

  it('expanding a session panel loads its messages', async () => {
    listMessages.mockResolvedValue({
      data: {
        messages: [
          { id: 'm-1', session_id: 's-1', role: 'user', content: '我想退货', latency_ms: null, created_at: null },
          { id: 'm-2', session_id: 's-1', role: 'assistant', content: '好的，请提供订单号', latency_ms: 320, created_at: null },
        ],
      },
    })
    render(<EvalReport ev={makeEval()} />)

    expect(listMessages).not.toHaveBeenCalled()
    fireEvent.click(screen.getByText('老客户'))
    await waitFor(() => expect(listMessages).toHaveBeenCalledWith('eval-1', 's-1'))
    expect(await screen.findByText('我想退货')).toBeInTheDocument()
    expect(screen.getByText('好的，请提供订单号')).toBeInTheDocument()
    expect(screen.getByText('320ms')).toBeInTheDocument()
  })

  it('exports the markdown report', async () => {
    downloadReportMarkdown.mockResolvedValue(undefined)
    render(<EvalReport ev={makeEval()} />)

    fireEvent.click(screen.getByText(/导出 Markdown/))
    await waitFor(() => expect(downloadReportMarkdown).toHaveBeenCalledWith('eval-1'))
  })
})
