import { fireEvent, render, screen, waitFor, within } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { describe, expect, it, vi, beforeEach } from 'vitest';

import { SearchTaskStatusPanel } from '@/components/shared/SearchTaskStatusPanel';
import { fetchSearchStatus, fetchSearchTasks } from '@/services/automationService';
import { TooltipProvider } from '@/components/ui/tooltip';

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

vi.mock('@/contexts/SearchManualInterventionContext', () => ({
  useSearchManualIntervention: () => ({
    previewSelectedSound: vi.fn(() => Promise.resolve()),
  }),
}));

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

describe('SearchTaskStatusPanel', () => {
  const fetchSearchTasksMock = vi.mocked(fetchSearchTasks);
  const fetchSearchStatusMock = vi.mocked(fetchSearchStatus);
  let queryClient: QueryClient;

  beforeEach(() => {
    fetchSearchTasksMock.mockReset();
    fetchSearchStatusMock.mockReset();
    queryClient = new QueryClient({
      defaultOptions: {
        queries: {
          retry: false,
          gcTime: 0,
        },
      },
    });
  });

  it('shows processing in the detail dialog when manual intervention is already inactive', async () => {
    fetchSearchTasksMock.mockResolvedValue({
      tasks: [{
        id: 'task-001',
        batch_id: 'CG-20260425-007',
        account_id: 'account-001',
        account_name: '13956047900',
        material_id: 'material-001',
        material_name: '防汛沙袋',
        status: 'processing',
        total_rows: 1,
        processed_rows: 0,
        completed_rows: 0,
        failed_rows: 0,
        stopped_rows: 0,
        current_material_id: 'material-001',
        current_item: '登录态已确认，开始搜索...',
        current_step_label: '登录态已确认，开始搜索...',
        display_progress_percent: 18,
        search_progress: {
          message: '登录态已确认，开始搜索...',
          materialId: 'material-001',
          materialName: '防汛沙袋',
          itemProgressPercent: 18,
          softCapPercent: null,
          stageStartedAt: '2026-04-28T07:00:00.000Z',
          metrics: {
            candidateCount: 128,
            nameMatchedCount: 17,
            qualifiedResultCount: 3,
            targetResultCount: 5,
          },
          updatedAt: '2026-04-28T07:02:00.000Z',
        },
        stage_timing: null,
        error_message: '',
        errors: [],
        started_at: '2026-04-28T07:00:00.000Z',
        paused_at: null,
        finished_at: null,
        created_at: '2026-04-28T07:00:00.000Z',
        updated_at: '2026-04-28T07:02:00.000Z',
        deletable: false,
      }],
      total: 1,
      summary: {
        total: 1,
        pending: 0,
        processing: 1,
        waiting_for_manual: 0,
        pausing: 0,
        paused: 0,
        stopping: 0,
        stopped: 0,
        completed: 0,
        failed: 0,
      },
    });

    fetchSearchStatusMock.mockResolvedValue({
      taskId: 'task-001',
      status: 'waiting_for_manual',
      batchId: 'CG-20260425-007',
      accountId: 'account-001',
      totalRows: 1,
      processedRows: 0,
      completedRows: 0,
      failedRows: 0,
      stoppedRows: 0,
      currentRow: 'material-001',
      currentItem: '登录态已确认，开始搜索...',
      currentStepLabel: '登录态已确认，开始搜索...',
      displayProgressPercent: 18,
      searchProgress: {
        message: '登录态已确认，开始搜索...',
        materialId: 'material-001',
        materialName: '防汛沙袋',
        itemProgressPercent: 18,
        softCapPercent: null,
        stageStartedAt: '2026-04-28T07:00:00.000Z',
        metrics: {
          candidateCount: 128,
          nameMatchedCount: 17,
          qualifiedResultCount: 3,
          targetResultCount: 5,
        },
        updatedAt: '2026-04-28T07:02:00.000Z',
      },
      stageTiming: null,
      errors: [],
      result: {
        manualIntervention: {
          active: false,
          taskId: 'task-001',
          batchId: 'CG-20260425-007',
          accountId: 'account-001',
          materialId: 'material-001',
          materialName: '防汛沙袋',
          message: '验证码已解除，继续执行自动搜索',
          detectedAt: '2026-04-28T07:00:00.000Z',
          resolvedAt: '2026-04-28T07:01:00.000Z',
          updatedAt: '2026-04-28T07:01:00.000Z',
        },
      },
      startedAt: '2026-04-28T07:00:00.000Z',
      pausedAt: null,
      finishedAt: null,
    });

    render(
      <QueryClientProvider client={queryClient}>
        <TooltipProvider>
          <SearchTaskStatusPanel
            active
            batchOptions={[]}
          />
        </TooltipProvider>
      </QueryClientProvider>,
    );

    await waitFor(() => {
      expect(screen.getAllByText('执行中').length).toBeGreaterThan(0);
      expect(screen.getByText('等待人工 0')).toBeInTheDocument();
      expect(screen.getAllByText(/商品 128 · 匹配 17 · 有效 3\/5/).length).toBeGreaterThan(0);
    });

    fireEvent.click(screen.getByText('防汛沙袋'));

    await waitFor(() => {
      const dialog = screen.getByRole('dialog');
      expect(within(dialog).getByText('任务详情')).toBeInTheDocument();
      expect(within(dialog).getByText('登录态已确认，开始搜索...')).toBeInTheDocument();
      expect(within(dialog).getByText('执行中')).toBeInTheDocument();
      expect(within(dialog).getByText('已获取商品：').parentElement).toHaveTextContent('已获取商品：128');
      expect(within(dialog).getByText('名称匹配：').parentElement).toHaveTextContent('名称匹配：17');
      expect(within(dialog).getByText('有效商家：').parentElement).toHaveTextContent('有效商家：3 / 5');
      expect(within(dialog).queryByText('等待人工')).not.toBeInTheDocument();
    });
  });

  it('renders completed stage timing in modular rows in the detail dialog', async () => {
    const stageTiming = {
      currentStage: null,
      completedStages: [{
        taskId: 'task-completed-001',
        materialId: 'material-001',
        materialName: '防汛沙袋',
        stageOrder: 1,
        stageLabel: '关键词搜索（AI 自动多轮）',
        stageKind: 'keyword',
        startedAt: '2026-04-28T07:00:00.000Z',
        endedAt: '2026-04-28T07:17:20.000Z',
        durationMs: 1040000,
        elapsedMs: 1040000,
        status: 'completed' as const,
      }],
      currentStep: null,
      completedSteps: [
        {
          taskId: 'task-completed-001',
          materialId: 'material-001',
          materialName: '防汛沙袋',
          stageOrder: 1,
          stageLabel: '关键词搜索（AI 自动多轮）',
          stageKind: 'keyword',
          stepKey: 'initial_search',
          stepLabel: '1688 初始搜索',
          startedAt: '2026-04-28T07:00:00.000Z',
          endedAt: '2026-04-28T07:08:30.000Z',
          durationMs: 510000,
          elapsedMs: 510000,
          status: 'completed' as const,
        },
        {
          taskId: 'task-completed-001',
          materialId: 'material-001',
          materialName: '防汛沙袋',
          stageOrder: 1,
          stageLabel: '关键词搜索（AI 自动多轮）',
          stageKind: 'keyword',
          stepKey: 'result_sync',
          stepLabel: '搜索结果同步',
          startedAt: '2026-04-28T07:08:30.000Z',
          endedAt: '2026-04-28T07:08:42.000Z',
          durationMs: 12000,
          elapsedMs: 12000,
          status: 'completed' as const,
        },
        {
          taskId: 'task-completed-001',
          materialId: 'material-001',
          materialName: '防汛沙袋',
          stageOrder: 1,
          stageLabel: '关键词搜索（AI 自动多轮）',
          stageKind: 'keyword',
          stepKey: 'too_fast',
          stepLabel: '瞬时步骤',
          startedAt: '2026-04-28T07:08:42.000Z',
          endedAt: '2026-04-28T07:08:42.300Z',
          durationMs: 300,
          elapsedMs: 300,
          status: 'completed' as const,
        },
      ],
      totalElapsedMs: 1040000,
    };

    fetchSearchTasksMock.mockResolvedValue({
      tasks: [{
        id: 'task-completed-001',
        batch_id: 'CG-20260425-008',
        account_id: 'account-001',
        account_name: '13956047900',
        material_id: 'material-001',
        material_name: '防汛沙袋',
        status: 'completed',
        total_rows: 1,
        processed_rows: 1,
        completed_rows: 1,
        failed_rows: 0,
        stopped_rows: 0,
        current_material_id: 'material-001',
        current_item: '搜索完成',
        current_step_label: '搜索完成',
        display_progress_percent: 100,
        search_progress: null,
        stage_timing: stageTiming,
        error_message: '',
        errors: [],
        started_at: '2026-04-28T07:00:00.000Z',
        paused_at: null,
        finished_at: '2026-04-28T07:17:20.000Z',
        created_at: '2026-04-28T07:00:00.000Z',
        updated_at: '2026-04-28T07:17:20.000Z',
        deletable: false,
      }],
      total: 1,
      summary: {
        total: 1,
        pending: 0,
        processing: 0,
        waiting_for_manual: 0,
        pausing: 0,
        paused: 0,
        stopping: 0,
        stopped: 0,
        completed: 1,
        failed: 0,
      },
    });

    fetchSearchStatusMock.mockResolvedValue({
      taskId: 'task-completed-001',
      status: 'completed',
      batchId: 'CG-20260425-008',
      accountId: 'account-001',
      totalRows: 1,
      processedRows: 1,
      completedRows: 1,
      failedRows: 0,
      stoppedRows: 0,
      currentRow: 'material-001',
      currentItem: '搜索完成',
      currentStepLabel: '搜索完成',
      displayProgressPercent: 100,
      searchProgress: null,
      stageTiming,
      errors: [],
      result: null,
      startedAt: '2026-04-28T07:00:00.000Z',
      pausedAt: null,
      finishedAt: '2026-04-28T07:17:20.000Z',
    });

    render(
      <QueryClientProvider client={queryClient}>
        <TooltipProvider>
          <SearchTaskStatusPanel
            active
            batchOptions={[]}
          />
        </TooltipProvider>
      </QueryClientProvider>,
    );

    await waitFor(() => {
      expect(screen.getAllByText('已完成').length).toBeGreaterThan(0);
    });

    fireEvent.click(screen.getByText('防汛沙袋'));

    await waitFor(() => {
      const dialog = screen.getByRole('dialog');
      expect(dialog.className).toContain('w-[calc(100vw-2rem)]');
      expect(dialog).toHaveClass('overflow-x-hidden');
      expect(within(dialog).queryByText('阶段 1 · 关键词搜索（AI 自动多轮）')).not.toBeInTheDocument();
      expect(within(dialog).getByText('总耗时 17分20秒')).toBeInTheDocument();
      expect(within(dialog).getByText('1688 初始搜索')).toBeInTheDocument();
      expect(within(dialog).getByText('搜索结果同步')).toBeInTheDocument();
      expect(within(dialog).queryByText('瞬时步骤')).not.toBeInTheDocument();
      expect(within(dialog).queryByText('0秒')).not.toBeInTheDocument();
      expect(within(dialog).getByText('1688 初始搜索').closest('.border-l')).toBeNull();
      const timingItem = within(dialog).getByText('1688 初始搜索').closest('div');
      expect(timingItem).toHaveClass('min-w-0');
      expect(within(dialog).getByText('1688 初始搜索')).toHaveClass('truncate');
      expect(timingItem?.parentElement?.className).toContain('grid-cols-[minmax(0,1fr)_minmax(0,1fr)]');
    });
  });
});
