import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom';
import { OrdersPage } from '@/client/admin/pages/Orders';
import { TestWrapper } from '~/utils/client/test-render';

// Import mocked modules
import { orderClient } from '@/client/api';
import { toast } from 'sonner';
import { OrderStatus, PaymentStatus } from '@d8d/server/share/order.types';

// Mock API 客户端
vi.mock('@/client/api', () => ({
  orderClient: {
    $get: vi.fn().mockResolvedValue({
      status: 200,
      ok: true,
      json: async () => ({
        data: [
          {
            id: 1,
            userId: 1,
            routeId: 1,
            passengerCount: 2,
            totalAmount: 100.5,
            status: OrderStatus.PENDING_PAYMENT,
            paymentStatus: PaymentStatus.PENDING,
            passengerSnapshots: [
              { name: '张三', idCard: '123456789012345678', phone: '13800138000' },
              { name: '李四', idCard: '123456789012345679', phone: '13800138001' }
            ],
            routeSnapshot: { name: '测试路线', description: '测试路线描述' },
            createdBy: 1,
            updatedBy: null,
            createdAt: '2024-01-01T00:00:00.000Z',
            updatedAt: '2024-01-01T00:00:00.000Z',
            user: {
              id: 1,
              username: 'testuser',
              phone: '13800138000'
            },
            route: {
              id: 1,
              name: '测试路线',
              description: '测试路线描述'
            }
          }
        ],
        total: 1,
        page: 1,
        pageSize: 10
      })
    }),
    stats: {
      $get: vi.fn().mockResolvedValue({
        status: 200,
        ok: true,
        json: async () => ({
          total: 10,
          pendingPayment: 2,
          waitingDeparture: 3,
          inProgress: 1,
          completed: 3,
          cancelled: 1
        })
      })
    }
  }
}));

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

describe('OrdersPage 集成测试', () => {
  const user = userEvent.setup();

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

  it('应该正确渲染订单管理页面标题', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    expect(screen.getByText('订单管理')).toBeInTheDocument();
  });

  it('应该显示订单统计面板', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByTestId('total-orders-count')).toHaveTextContent('10'); // 总订单数
      expect(screen.getByTestId('pending-payment-count')).toHaveTextContent('2'); // 待支付数量
      expect(screen.getByTestId('waiting-departure-count')).toHaveTextContent('3'); // 待出发数量
      expect(screen.getByTestId('in-progress-count')).toHaveTextContent('1'); // 行程中数量
      expect(screen.getByTestId('completed-count')).toHaveTextContent('3'); // 已完成数量
      expect(screen.getByTestId('cancelled-count')).toHaveTextContent('1'); // 已取消数量
    });
  });

  it('应该显示订单列表和搜索功能', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByPlaceholderText('搜索订单号、用户信息...')).toBeInTheDocument();
    });

    expect(screen.getByText('搜索')).toBeInTheDocument();
    expect(screen.getByText('高级筛选')).toBeInTheDocument();
  });

  it('应该处理搜索功能', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    const searchInput = screen.getByPlaceholderText('搜索订单号、用户信息...');
    const searchButton = screen.getByText('搜索');

    // 输入搜索关键词
    await user.type(searchInput, 'testuser');
    await user.click(searchButton);

    // 验证搜索参数被设置
    expect(searchInput).toHaveValue('testuser');
  });

  it('应该显示高级筛选功能', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    const filterButton = screen.getByRole('button', { name: '高级筛选' });
    await user.click(filterButton);

    // 验证筛选表单显示
    expect(screen.getByText('订单状态')).toBeInTheDocument();
    expect(screen.getByText('支付状态')).toBeInTheDocument();
  });

  it('应该处理订单状态筛选', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    const filterButton = screen.getByRole('button', { name: '高级筛选' });
    await user.click(filterButton);

    // 验证筛选表单显示和状态筛选标签
    expect(screen.getByText('订单状态')).toBeInTheDocument();

    // 验证状态筛选器存在（通过查找Select组件）
    const selectElements = document.querySelectorAll('[role="combobox"]');
    expect(selectElements.length).toBeGreaterThan(0);
  });

  it('应该显示分页组件', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    // 验证分页控件存在
    await waitFor(() => {
      expect(screen.getByText(/共 \d+ 个订单/)).toBeInTheDocument();
    });
  });

  it('应该处理表格数据加载状态', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    // 验证骨架屏或加载状态
    const skeletonElements = document.querySelectorAll('[data-slot="skeleton"]');
    expect(skeletonElements.length).toBeGreaterThan(0);

    // 等待数据加载完成
    await waitFor(() => {
      expect(screen.getByText('testuser')).toBeInTheDocument();
    });
  });

  it('应该显示正确的表格列标题', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    // 等待数据加载
    await waitFor(() => {
      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('创建时间')).toBeInTheDocument();
      expect(screen.getByText('操作')).toBeInTheDocument();
    });
  });

  it('应该包含查看详情操作按钮', async () => {
    const { container } = render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    // 等待数据加载完成
    await waitFor(() => {
      expect(screen.getByText('testuser')).toBeInTheDocument();

      // 查找操作按钮（通过按钮元素）
      const actionButtons = container.querySelectorAll('button');
      const hasViewButtons = Array.from(actionButtons).some(button =>
        button.innerHTML.includes('eye')
      );

      expect(hasViewButtons).toBe(true);
    });
  });

  it('应该打开订单详情对话框', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

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

    // 查找查看详情按钮
    const viewButtons = screen.getAllByRole('button').filter(btn =>
      btn.innerHTML.includes('eye')
    );

    if (viewButtons.length > 0) {
      await user.click(viewButtons[0]);

      // 验证详情对话框打开
      await waitFor(() => {
        expect(screen.getByRole('heading', { name: '订单详情' })).toBeInTheDocument();
      });
    }
  });

  it('应该在详情对话框中显示订单信息', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

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

    // 查找查看详情按钮
    const viewButtons = screen.getAllByRole('button').filter(btn =>
      btn.innerHTML.includes('eye')
    );

    if (viewButtons.length > 0) {
      await user.click(viewButtons[0]);

      // 验证详情对话框内容
      await waitFor(() => {
        expect(screen.getByText('订单信息')).toBeInTheDocument();
        expect(screen.getByText('用户信息')).toBeInTheDocument();
        expect(screen.getByText('路线信息')).toBeInTheDocument();
        expect(screen.getByText('订单详情')).toBeInTheDocument();
        expect(screen.getByText('乘客信息')).toBeInTheDocument();

        // 验证具体数据
        expect(screen.getByText('#1')).toBeInTheDocument(); // 订单号
        expect(screen.getByText('待支付')).toBeInTheDocument(); // 订单状态
        expect(screen.getByText('testuser')).toBeInTheDocument(); // 用户名
        expect(screen.getByText('测试路线')).toBeInTheDocument(); // 路线名称
        expect(screen.getByText('2')).toBeInTheDocument(); // 乘客数量
        expect(screen.getByText('¥100.5')).toBeInTheDocument(); // 订单金额
      });
    }
  });

  it('应该处理API错误场景', async () => {
    // 模拟API错误
    (orderClient.$get as any).mockResolvedValueOnce({
      status: 500,
      ok: false,
      json: async () => ({ error: 'Internal server error' })
    });

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

    // 验证页面仍然渲染基本结构
    expect(screen.getByText('订单管理')).toBeInTheDocument();

    // 验证错误处理（组件应该优雅处理错误）
    await waitFor(() => {
      expect(screen.queryByText('testuser')).not.toBeInTheDocument();
    });
  });

  it('应该处理响应式布局', async () => {
    const { container } = render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

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

    // 展开筛选表单以显示响应式网格
    const filterButton = screen.getByRole('button', { name: '高级筛选' });
    await user.click(filterButton);

    // 验证响应式网格类名
    const gridElements = container.querySelectorAll('.grid');
    expect(gridElements.length).toBeGreaterThan(0);

    // 验证响应式类名存在
    const hasResponsiveClasses = container.innerHTML.includes('md:grid-cols-2');
    expect(hasResponsiveClasses).toBe(true);
  });

  it('应该显示订单总数信息', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    // 验证订单总数显示
    await waitFor(() => {
      expect(screen.getByText(/共 \d+ 个订单/)).toBeInTheDocument();
    });
  });

  it('应该处理统计API错误场景', async () => {
    // 模拟统计API错误
    (orderClient.stats.$get as any).mockResolvedValueOnce({
      status: 500,
      ok: false,
      json: async () => ({ error: 'Internal server error' })
    });

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

    // 验证页面仍然渲染基本结构
    expect(screen.getByText('订单管理')).toBeInTheDocument();

    // 验证统计面板显示默认值
    await waitFor(() => {
      expect(screen.getByText('总订单数')).toBeInTheDocument();
      expect(screen.getByText('0')).toBeInTheDocument(); // 默认值
    });
  });

  it('应该处理防抖搜索功能', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    const searchInput = screen.getByPlaceholderText('搜索订单号、用户信息...');

    // 快速输入多个字符
    await user.type(searchInput, 'test');
    await user.type(searchInput, 'user');

    // 验证输入值正确
    expect(searchInput).toHaveValue('testuser');

    // 等待防抖延迟
    await waitFor(() => {
      expect(orderClient.$get).toHaveBeenCalled();
    }, { timeout: 500 });
  });

  it('应该处理筛选条件重置', async () => {
    render(
      <TestWrapper>
        <OrdersPage />
      </TestWrapper>
    );

    // 打开筛选
    const filterButton = screen.getByRole('button', { name: '高级筛选' });
    await user.click(filterButton);

    // 设置筛选条件
    const statusSelect = document.querySelectorAll('[role="combobox"]')[0];
    await user.click(statusSelect);

    // 选择订单状态
    const statusOption = screen.getByText('待支付');
    await user.click(statusOption);

    // 验证重置按钮显示
    const resetButton = screen.getByRole('button', { name: '重置' });
    expect(resetButton).toBeInTheDocument();

    // 点击重置
    await user.click(resetButton);

    // 验证筛选条件被重置
    expect(screen.queryByText('待支付')).not.toBeInTheDocument();
  });
});