import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { UserSelector } from '../../src/components/UserSelector';
import { userClient } from '../../src/api/userClient';

// 完整的mock响应对象
const createMockResponse = (status: number, data?: any) => ({
  status,
  ok: status >= 200 && status < 300,
  body: null,
  bodyUsed: false,
  statusText: status === 200 ? 'OK' : status === 201 ? 'Created' : status === 204 ? 'No Content' : 'Error',
  headers: new Headers(),
  url: '',
  redirected: false,
  type: 'basic' as ResponseType,
  json: async () => data || {},
  text: async () => '',
  blob: async () => new Blob(),
  arrayBuffer: async () => new ArrayBuffer(0),
  formData: async () => new FormData(),
  clone: function() { return this; }
});

// Mock API client
vi.mock('../../src/api/userClient', () => {
  const mockUserClient = {
    $get: vi.fn(() => Promise.resolve({
      status: 200,
      body: null,
      json: async () => ({ data: [], pagination: { total: 0, page: 1, pageSize: 100 } })
    })),
  };

  const mockUserClientManager = {
    get: vi.fn(() => mockUserClient),
  };

  return {
    userClientManager: mockUserClientManager,
    userClient: mockUserClient,
  };
});

const createTestQueryClient = () =>
  new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
        enabled: true,
      },
    },
  });

const renderWithProviders = (component: React.ReactElement) => {
  const queryClient = createTestQueryClient();
  return render(
    <QueryClientProvider client={queryClient}>
      {component as any}
    </QueryClientProvider>
  );
};

describe('用户选择器集成测试', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('应该加载并显示用户列表', async () => {
    const mockUsers = {
      data: [
        {
          id: 1,
          username: 'user1',
          name: 'User One',
          email: 'user1@example.com',
          phone: '1234567890',
        },
        {
          id: 2,
          username: 'user2',
          name: 'User Two',
          email: 'user2@example.com',
          phone: '0987654321',
        },
      ],
      pagination: {
        total: 2,
        page: 1,
        pageSize: 100,
      },
    };

    // Mock user list API
    (userClient.$get as any).mockResolvedValue(createMockResponse(200, mockUsers));

    renderWithProviders(<UserSelector testId="user-selector" />);

    // Open select dropdown to trigger API call
    const selectTrigger = screen.getByTestId('user-selector');
    fireEvent.click(selectTrigger);

    // Wait for API call and loading to complete
    await waitFor(() => {
      expect(userClient.$get).toHaveBeenCalledWith({
        query: {
          page: 1,
          pageSize: 100,
        },
      });
    });

    // Verify select trigger is rendered
    expect(selectTrigger).toBeInTheDocument();
  });

  it('应该处理用户选择', async () => {
    const mockUsers = {
      data: [
        {
          id: 1,
          username: 'user1',
          name: 'User One',
          email: 'user1@example.com',
          phone: '1234567890',
        },
      ],
      pagination: {
        total: 1,
        page: 1,
        pageSize: 100,
      },
    };

    const mockOnChange = vi.fn();

    // Mock user list API
    (userClient.$get as any).mockResolvedValue(createMockResponse(200, mockUsers));

    renderWithProviders(
      <UserSelector onChange={mockOnChange} testId="user-selector" />
    );

    // Wait for API call
    await waitFor(() => {
      expect(userClient.$get).toHaveBeenCalledWith({
        query: {
          page: 1,
          pageSize: 100,
        },
      });
    });

    // Verify select trigger is rendered
    const selectTrigger = screen.getByTestId('user-selector');
    expect(selectTrigger).toBeInTheDocument();

    // Verify onChange callback is properly passed
    expect(mockOnChange).not.toHaveBeenCalled();
  });

  it('应该显示自定义占位符', async () => {
    const mockUsers = {
      data: [],
      pagination: {
        total: 0,
        page: 1,
        pageSize: 100,
      },
    };

    // Mock empty user list
    (userClient.$get as any).mockResolvedValue(createMockResponse(200, mockUsers));

    renderWithProviders(
      <UserSelector placeholder="请选择用户" testId="user-selector" />
    );

    // Open select dropdown to trigger API call
    const selectTrigger = screen.getByTestId('user-selector');
    fireEvent.click(selectTrigger);

    // Wait for API call
    await waitFor(() => {
      expect(userClient.$get).toHaveBeenCalled();
    });

    // Verify custom placeholder is shown
    expect(selectTrigger).toHaveTextContent('请选择用户');
  });

  it('应该处理禁用状态', async () => {
    const mockUsers = {
      data: [
        {
          id: 1,
          username: 'user1',
          name: 'User One',
          email: 'user1@example.com',
          phone: '1234567890',
        },
      ],
      pagination: {
        total: 1,
        page: 1,
        pageSize: 100,
      },
    };

    // Mock user list API
    (userClient.$get as any).mockResolvedValue(createMockResponse(200, mockUsers));

    renderWithProviders(
      <UserSelector disabled={true} testId="user-selector" />
    );

    // Verify select is disabled immediately (no need to wait for API call)
    const selectTrigger = screen.getByTestId('user-selector');
    expect(selectTrigger).toBeDisabled();
  });

  it('应该处理API错误', async () => {
    // Mock API error
    (userClient.$get as any).mockRejectedValue(new Error('API Error'));

    renderWithProviders(<UserSelector testId="user-selector" />);

    // Should handle error without crashing
    await waitFor(() => {
      expect(screen.getByTestId('user-selector')).toBeInTheDocument();
    });
  });

  it('应该显示预选值', async () => {
    const mockUsers = {
      data: [
        {
          id: 1,
          username: 'user1',
          name: 'User One',
          email: 'user1@example.com',
          phone: '1234567890',
        },
        {
          id: 2,
          username: 'user2',
          name: 'User Two',
          email: 'user2@example.com',
          phone: '0987654321',
        },
      ],
      pagination: {
        total: 2,
        page: 1,
        pageSize: 100,
      },
    };

    // Mock user list API
    (userClient.$get as any).mockResolvedValue(createMockResponse(200, mockUsers));

    renderWithProviders(
      <UserSelector value={2} testId="user-selector" />
    );

    // Wait for data to load
    await waitFor(() => {
      expect(userClient.$get).toHaveBeenCalled();
    });

    // Verify the select has the correct value
    const selectTrigger = screen.getByTestId('user-selector');
    expect(selectTrigger).toHaveAttribute('data-state', 'closed');
  });
});