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 { UserManagement } from '../../src/components/UserManagement';

// Mock API client
vi.mock('../../src/api/userClient', () => ({
  userClient: {
    $get: vi.fn(),
    $post: vi.fn(),
    ':id': {
      $put: vi.fn(),
      $delete: vi.fn(),
    },
  },
}));

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

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

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

describe('UserManagement Integration Tests', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('should complete full user CRUD flow', async () => {
    const mockUsers = {
      data: [
        {
          id: 1,
          username: 'existinguser',
          nickname: 'Existing User',
          email: 'existing@example.com',
          phone: '1234567890',
          name: 'Existing Name',
          isDisabled: 0,
          createdAt: '2024-01-01T00:00:00Z',
          roles: [{ id: 1, name: 'admin' }],
          avatarFile: null,
        },
      ],
      pagination: {
        total: 1,
        page: 1,
        pageSize: 10,
      },
    };

    const { userClient } = await import('../../src/api/userClient');
    const { toast } = await import('sonner');

    // Mock initial user list
    (userClient.index.$get as any).mockResolvedValue({
      status: 200,
      json: async () => mockUsers,
    });

    renderWithProviders(<UserManagement />);

    // Wait for initial data to load
    await waitFor(() => {
      expect(screen.getByText('existinguser')).toBeInTheDocument();
    });

    // Test create user
    const createButton = screen.getByText('创建用户');
    fireEvent.click(createButton);

    // Fill create form
    const usernameInput = screen.getByPlaceholderText('请输入用户名');
    const passwordInput = screen.getByPlaceholderText('请输入密码');
    const emailInput = screen.getByPlaceholderText('请输入邮箱');

    fireEvent.change(usernameInput, { target: { value: 'newuser' } });
    fireEvent.change(passwordInput, { target: { value: 'password123' } });
    fireEvent.change(emailInput, { target: { value: 'new@example.com' } });

    // Mock successful creation
    (userClient.index.$post as any).mockResolvedValue({
      status: 201,
    });

    const submitButton = screen.getByText('创建用户');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(userClient.index.$post).toHaveBeenCalledWith({
        json: {
          username: 'newuser',
          password: 'password123',
          email: 'new@example.com',
          nickname: undefined,
          phone: null,
          name: null,
          isDisabled: 0,
        },
      });
      expect(toast.success).toHaveBeenCalledWith('用户创建成功');
    });

    // Test edit user
    const editButtons = screen.getAllByRole('button', { name: /edit/i });
    fireEvent.click(editButtons[0]);

    // Verify edit form is populated
    await waitFor(() => {
      expect(screen.getByDisplayValue('existinguser')).toBeInTheDocument();
    });

    // Update user
    const updateUsernameInput = screen.getByDisplayValue('existinguser');
    fireEvent.change(updateUsernameInput, { target: { value: 'updateduser' } });

    // Mock successful update
    (userClient[':id']['$put'] as any).mockResolvedValue({
      status: 200,
    });

    const updateButton = screen.getByText('更新用户');
    fireEvent.click(updateButton);

    await waitFor(() => {
      expect(userClient[':id']['$put']).toHaveBeenCalledWith({
        param: { id: 1 },
        json: {
          username: 'updateduser',
          nickname: 'Existing User',
          email: 'existing@example.com',
          phone: '1234567890',
          name: 'Existing Name',
          password: undefined,
          avatarFileId: null,
          isDisabled: 0,
        },
      });
      expect(toast.success).toHaveBeenCalledWith('用户更新成功');
    });

    // Test delete user
    const deleteButtons = screen.getAllByRole('button', { name: /trash/i });
    fireEvent.click(deleteButtons[0]);

    // Confirm deletion
    expect(screen.getByText('确认删除')).toBeInTheDocument();

    // Mock successful deletion
    (userClient[':id']['$delete'] as any).mockResolvedValue({
      status: 204,
    });

    const confirmDeleteButton = screen.getByText('删除');
    fireEvent.click(confirmDeleteButton);

    await waitFor(() => {
      expect(userClient[':id']['$delete']).toHaveBeenCalledWith({
        param: { id: 1 },
      });
      expect(toast.success).toHaveBeenCalledWith('用户删除成功');
    });
  });

  it('should handle API errors gracefully', async () => {
    const { userClient } = await import('../../src/api/userClient');
    const { toast } = await import('sonner');

    // Mock API error
    (userClient.index.$get as any).mockRejectedValue(new Error('API Error'));

    renderWithProviders(<UserManagement />);

    // Should handle error without crashing
    await waitFor(() => {
      expect(screen.getByText('用户管理')).toBeInTheDocument();
    });

    // Test create user error
    const createButton = screen.getByText('创建用户');
    fireEvent.click(createButton);

    const usernameInput = screen.getByPlaceholderText('请输入用户名');
    const passwordInput = screen.getByPlaceholderText('请输入密码');

    fireEvent.change(usernameInput, { target: { value: 'testuser' } });
    fireEvent.change(passwordInput, { target: { value: 'password' } });

    // Mock creation error
    (userClient.index.$post as any).mockRejectedValue(new Error('Creation failed'));

    const submitButton = screen.getByText('创建用户');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(toast.error).toHaveBeenCalledWith('创建失败，请重试');
    });
  });

  it('should handle search and filter integration', async () => {
    const { userClient } = await import('../../src/api/userClient');

    const mockUsers = {
      data: [],
      pagination: { total: 0, page: 1, pageSize: 10 },
    };

    (userClient.index.$get as any).mockResolvedValue({
      status: 200,
      json: async () => mockUsers,
    });

    renderWithProviders(<UserManagement />);

    // Test search
    const searchInput = screen.getByPlaceholderText('搜索用户名、昵称或邮箱...');
    fireEvent.change(searchInput, { target: { value: 'searchterm' } });

    await waitFor(() => {
      expect(userClient.index.$get).toHaveBeenCalledWith({
        query: {
          page: 1,
          pageSize: 10,
          keyword: 'searchterm',
          filters: undefined,
        },
      });
    });

    // Test filter
    const filterButton = screen.getByText('高级筛选');
    fireEvent.click(filterButton);

    // Apply status filter
    const statusSelect = screen.getByText('选择状态');
    fireEvent.click(statusSelect);

    const enabledOption = screen.getByText('启用');
    fireEvent.click(enabledOption);

    await waitFor(() => {
      expect(userClient.index.$get).toHaveBeenCalledWith({
        query: {
          page: 1,
          pageSize: 10,
          keyword: 'searchterm',
          filters: expect.stringContaining('isDisabled'),
        },
      });
    });
  });
});