import { render, screen, waitFor } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';

import { SearchProgressDialog } from '@/components/shared/SearchProgressDialog';
import { fetchSearchStatus } from '@/services/automationService';

vi.mock('@/services/automationService', async () => {
  const actual = await vi.importActual<typeof import('@/services/automationService')>('@/services/automationService');
  return {
    ...actual,
    fetchSearchStatus: vi.fn(),
    pauseSearchBatch: vi.fn(),
    resumeSearchBatch: vi.fn(),
    stopSearchBatch: vi.fn(),
  };
});

vi.mock('sonner', () => ({
  toast: {
    info: vi.fn(),
    success: vi.fn(),
    error: vi.fn(),
  },
}));

describe('SearchProgressDialog', () => {
  const fetchSearchStatusMock = vi.mocked(fetchSearchStatus);

  it('renders an empty state when the current user has no visible search task', async () => {
    fetchSearchStatusMock.mockResolvedValue({
      taskId: '',
      status: 'idle',
      batchId: '',
      accountId: '',
      totalRows: 0,
      processedRows: 0,
      completedRows: 0,
      failedRows: 0,
      stoppedRows: 0,
      currentRow: '',
      currentItem: '',
      errors: [],
      result: null,
      startedAt: null,
      pausedAt: null,
      finishedAt: null,
    });

    render(
      <SearchProgressDialog
        open
        onOpenChange={vi.fn()}
        taskId={null}
        onTaskIdChange={vi.fn()}
      />,
    );

    await waitFor(() => {
      expect(screen.getByText('当前没有可查看的搜索任务')).toBeInTheDocument();
      expect(screen.getByText(/启动新任务后，可以在这里查看进度/)).toBeInTheDocument();
    });
  });

  it('renders processing controls for an active search task', async () => {
    fetchSearchStatusMock.mockResolvedValue({
      taskId: 'task-001',
      status: 'processing',
      batchId: 'CG-TEST-001',
      accountId: 'account-001',
      totalRows: 10,
      processedRows: 2,
      completedRows: 2,
      failedRows: 0,
      stoppedRows: 0,
      currentRow: 'material-002',
      currentItem: '正在处理第 3 行',
      errors: [],
      result: null,
      startedAt: '2026-04-21T08:00:00.000Z',
      pausedAt: null,
      finishedAt: null,
    });

    render(
      <SearchProgressDialog
        open
        onOpenChange={vi.fn()}
        taskId="task-001"
        onTaskIdChange={vi.fn()}
      />,
    );

    await waitFor(() => {
      expect(screen.getByText('搜索进行中')).toBeInTheDocument();
      expect(screen.getByRole('button', { name: '暂停搜索' })).toBeInTheDocument();
      expect(screen.getByRole('button', { name: '停止搜索' })).toBeInTheDocument();
    });
  });

  it('renders LLM matching step text and display progress', async () => {
    fetchSearchStatusMock.mockResolvedValue({
      taskId: 'task-llm',
      status: 'processing',
      batchId: 'CG-TEST-LLM',
      accountId: 'account-llm',
      totalRows: 1,
      processedRows: 0,
      completedRows: 0,
      failedRows: 0,
      stoppedRows: 0,
      currentRow: 'material-llm',
      currentItem: '正在搜索: 测试物料',
      currentStepLabel: '正在调用大模型判断商品匹配，请稍候...',
      displayProgressPercent: 45,
      searchProgress: {
        message: '正在调用大模型判断商品匹配，请稍候...',
        materialId: 'material-llm',
        materialName: '测试物料',
        itemProgressPercent: 45,
        softCapPercent: null,
        stageStartedAt: '2026-04-22T08:00:00.000Z',
        updatedAt: '2026-04-22T08:00:00.000Z',
      },
      errors: [],
      result: null,
      startedAt: '2026-04-22T07:50:00.000Z',
      pausedAt: null,
      finishedAt: null,
    });

    render(
      <SearchProgressDialog
        open
        onOpenChange={vi.fn()}
        taskId="task-llm"
        onTaskIdChange={vi.fn()}
      />,
    );

    await waitFor(() => {
      expect(screen.getByText('正在调用大模型判断商品匹配，请稍候...')).toBeInTheDocument();
      expect(screen.getByText('45%')).toBeInTheDocument();
    });
  });

  it('renders pause controls while waiting for manual intervention', async () => {
    fetchSearchStatusMock.mockResolvedValue({
      taskId: 'task-002',
      status: 'waiting_for_manual',
      batchId: 'CG-TEST-002',
      accountId: 'account-002',
      totalRows: 10,
      processedRows: 4,
      completedRows: 4,
      failedRows: 0,
      stoppedRows: 0,
      currentRow: 'material-004',
      currentItem: '等待人工处理验证码',
      errors: [],
      result: {
        success: false,
        stopped: false,
        processedRows: 4,
        totalRows: 10,
        completedRows: 4,
        failedRows: 0,
        stoppedRows: 0,
        errorCount: 0,
        error: '',
        manualIntervention: {
          active: true,
          taskId: 'task-002',
          batchId: 'CG-TEST-002',
          accountId: 'account-002',
          materialId: 'material-004',
          materialName: '测试物料',
          message: '等待人工处理验证码',
          detectedAt: '2026-04-22T08:00:00.000Z',
        },
      },
      startedAt: '2026-04-22T07:50:00.000Z',
      pausedAt: null,
      finishedAt: null,
    });

    render(
      <SearchProgressDialog
        open
        onOpenChange={vi.fn()}
        taskId="task-002"
        onTaskIdChange={vi.fn()}
      />,
    );

    await waitFor(() => {
      expect(screen.getByText('等待人工处理')).toBeInTheDocument();
      expect(screen.getByRole('button', { name: '暂停搜索' })).toBeInTheDocument();
      expect(screen.getByRole('button', { name: '停止搜索' })).toBeInTheDocument();
    });
  });
});
