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

import { AdvertisementTypeManagement } from '../../src/components/AdvertisementTypeManagement';
import { advertisementTypeClient } from '../../src/api/advertisementTypeClient';

// Mock the advertisement type client
vi.mock('../../src/api/advertisementTypeClient', () => {
  const advertisementTypeClient = {
    index: {
      $get: vi.fn(),
      $post: vi.fn(),
    },
    ':id': {
      $put: vi.fn(),
      $delete: vi.fn(),
    },
  }
  return {
    advertisementTypeClient,
    advertisementTypeClientManager: {
      get: vi.fn(() => advertisementTypeClient),
    },
  }
})

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

// 测试包装器组件
const TestWrapper = ({ children }: { children: React.ReactNode }) => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
      },
    },
  });

  return (
    <BrowserRouter>
      <QueryClientProvider client={queryClient}>
        {children as any}
      </QueryClientProvider>
    </BrowserRouter>
  );
};

// 测试数据
const mockAdvertisementTypes = {
  data: [
    {
      id: 1,
      name: '首页轮播',
      code: 'home_carousel',
      remark: '首页轮播广告位',
      status: 1,
      createdAt: '2024-01-01T00:00:00Z',
      updatedAt: '2024-01-01T00:00:00Z',
      createdBy: 1,
      updatedBy: 1,
    },
    {
      id: 2,
      name: '侧边广告',
      code: 'sidebar_ad',
      remark: '侧边栏广告位',
      status: 0,
      createdAt: '2024-01-02T00:00:00Z',
      updatedAt: '2024-01-02T00:00:00Z',
      createdBy: 1,
      updatedBy: 1,
    },
  ],
  pagination: {
    total: 2,
    page: 1,
    pageSize: 10,
    totalPages: 1,
  },
};

describe('AdvertisementTypeManagement 集成测试', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('应该正确渲染广告类型管理界面', async () => {
    // Mock API响应
    (advertisementTypeClient.index.$get as any).mockResolvedValue({
      status: 200,
      json: async () => mockAdvertisementTypes,
    });

    render(
      <TestWrapper>
        <AdvertisementTypeManagement />
      </TestWrapper>
    );

    // 验证标题和描述
    expect(screen.getByTestId('page-title')).toHaveTextContent('广告类型管理');
    expect(screen.getByTestId('page-description')).toHaveTextContent('管理广告类型配置，用于广告位分类');

    // 等待数据加载完成
    await waitFor(() => {
      expect(screen.getByTestId('type-row-1')).toBeInTheDocument();
      expect(screen.getByTestId('type-row-2')).toBeInTheDocument();
    });

    // 验证表格列
    expect(screen.getByText('ID')).toBeInTheDocument();
    expect(screen.getByText('类型名称')).toBeInTheDocument();
    expect(screen.getByText('调用别名')).toBeInTheDocument();
    expect(screen.getByText('状态')).toBeInTheDocument();
    expect(screen.getByText('创建时间')).toBeInTheDocument();
    expect(screen.getByText('操作')).toBeInTheDocument();

    // 验证状态显示
    expect(screen.getByText('启用')).toBeInTheDocument();
    expect(screen.getByText('禁用')).toBeInTheDocument();

    // 验证调用别名显示
    expect(screen.getByText('home_carousel')).toBeInTheDocument();
    expect(screen.getByText('sidebar_ad')).toBeInTheDocument();
  });

  it('应该显示加载状态', () => {
    // Mock 延迟响应
    (advertisementTypeClient.index.$get as any).mockImplementation(
      () => new Promise(() => {}) // 永不解析的Promise
    );

    render(
      <TestWrapper>
        <AdvertisementTypeManagement />
      </TestWrapper>
    );

    // 验证加载状态
    expect(screen.getByTestId('page-title')).toHaveTextContent('广告类型管理');
    expect(screen.getByTestId('create-type-button')).toBeInTheDocument();
    expect(screen.getByTestId('create-type-button')).toBeDisabled();
  });

  it('应该处理搜索功能', async () => {
    (advertisementTypeClient.index.$get as any).mockResolvedValue({
      status: 200,
      json: async () => mockAdvertisementTypes,
    });

    render(
      <TestWrapper>
        <AdvertisementTypeManagement />
      </TestWrapper>
    );

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByText('首页轮播')).toBeInTheDocument();
    });

    // 获取搜索输入框
    const searchInput = screen.getByTestId('search-input');
    const searchButton = screen.getByTestId('search-button');

    // 输入搜索关键词
    fireEvent.change(searchInput, { target: { value: '首页' } });
    fireEvent.click(searchButton);

    // 验证API调用
    await waitFor(() => {
      expect(advertisementTypeClient.index.$get).toHaveBeenCalledWith({
        query: {
          page: 1,
          pageSize: 10,
          keyword: '首页',
        },
      });
    });
  });

  it('应该打开创建广告类型模态框', async () => {
    (advertisementTypeClient.index.$get as any).mockResolvedValue({
      status: 200,
      json: async () => mockAdvertisementTypes,
    });

    render(
      <TestWrapper>
        <AdvertisementTypeManagement />
      </TestWrapper>
    );

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByTestId('type-row-1')).toBeInTheDocument();
    });

    // 点击创建按钮
    const createButton = screen.getByTestId('create-type-button');
    fireEvent.click(createButton);

    // 验证模态框打开
    await waitFor(() => {
      expect(screen.getByTestId('modal-title')).toHaveTextContent('创建广告类型');
    });

    // 验证表单字段
    expect(screen.getByTestId('create-name-input')).toBeInTheDocument();
    expect(screen.getByTestId('create-code-input')).toBeInTheDocument();
    expect(screen.getByTestId('create-remark-textarea')).toBeInTheDocument();
    expect(screen.getByTestId('create-status-switch')).toBeInTheDocument();
  });

  it('应该打开编辑广告类型模态框', async () => {
    (advertisementTypeClient.index.$get as any).mockResolvedValue({
      status: 200,
      json: async () => mockAdvertisementTypes,
    });

    render(
      <TestWrapper>
        <AdvertisementTypeManagement />
      </TestWrapper>
    );

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByTestId('type-row-1')).toBeInTheDocument();
    });

    // 点击编辑按钮
    const editButton = screen.getByTestId('edit-button-1');
    fireEvent.click(editButton);

    // 验证模态框打开
    await waitFor(() => {
      expect(screen.getByTestId('modal-title')).toHaveTextContent('编辑广告类型');
    });

    // 验证表单预填充数据
    const nameInput = screen.getByTestId('edit-name-input');
    expect(nameInput).toHaveValue('首页轮播');
  });

  it('应该处理删除确认对话框', async () => {
    (advertisementTypeClient.index.$get as any).mockResolvedValue({
      status: 200,
      json: async () => mockAdvertisementTypes,
    });

    render(
      <TestWrapper>
        <AdvertisementTypeManagement />
      </TestWrapper>
    );

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByTestId('type-row-1')).toBeInTheDocument();
    });

    // 点击删除按钮
    const deleteButton = screen.getByTestId('delete-button-1');
    fireEvent.click(deleteButton);

    // 验证删除确认对话框打开
    await waitFor(() => {
      expect(screen.getByTestId('delete-dialog')).toBeInTheDocument();
      expect(screen.getByTestId('delete-dialog-title')).toHaveTextContent('确认删除');
      expect(screen.getByTestId('delete-dialog-description')).toHaveTextContent(/确定要删除这个广告类型吗/);
    });
  });

  it('应该显示空状态', async () => {
    // Mock 空数据响应
    (advertisementTypeClient.index.$get as any).mockResolvedValue({
      status: 200,
      json: async () => ({
        data: [],
        pagination: {
          total: 0,
          page: 1,
          pageSize: 10,
          totalPages: 0,
        },
      }),
    });

    render(
      <TestWrapper>
        <AdvertisementTypeManagement />
      </TestWrapper>
    );

    // 验证空状态显示
    await waitFor(() => {
      expect(screen.getByText('暂无广告类型数据')).toBeInTheDocument();
    });
  });

  it('应该处理分页', async () => {
    (advertisementTypeClient.index.$get as any).mockResolvedValue({
      status: 200,
      json: async () => mockAdvertisementTypes,
    });

    render(
      <TestWrapper>
        <AdvertisementTypeManagement />
      </TestWrapper>
    );

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByTestId('type-row-1')).toBeInTheDocument();
    });

    // 验证分页信息
    expect(screen.getByText('共 2 条记录')).toBeInTheDocument();
    expect(screen.getByTestId('current-page-info')).toHaveTextContent('第 1 页');

    // 验证分页按钮存在
    const nextButton = screen.getByTestId('next-page-button');
    expect(nextButton).toBeInTheDocument();

    const prevButton = screen.getByTestId('prev-page-button');
    expect(prevButton).toBeInTheDocument();

    // 验证上一页按钮被禁用（当前是第一页）
    expect(prevButton).toBeDisabled();
  });
});