import React from 'react';
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 { AreaManagement } from '../../src/components/AreaManagement';
import { areaClient } from '../../src/api/areaClient';

// 完整的mock响应对象 - 按照用户UI包规范
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 areaClient - 按照用户UI包规范
vi.mock('../../src/api/areaClient', () => {
  const mockAreaClient = {
    index: {
      $get: vi.fn(() => Promise.resolve({ status: 200, body: null })),
      $post: vi.fn(() => Promise.resolve({ status: 201, body: null })),
    },
    ':id': {
      $put: vi.fn(() => Promise.resolve({ status: 200, body: null })),
      $delete: vi.fn(() => Promise.resolve({ status: 204, body: null })),
    },
  };

  const mockAreaClientManager = {
    get: vi.fn(() => mockAreaClient),
  };

  return {
    areaClientManager: mockAreaClientManager,
    areaClient: mockAreaClient,
  };
});

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

// Test wrapper component
const TestWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
      },
    },
  });

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

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

  it('should render area management component with title', async () => {
    // Mock successful API response for province data
    (areaClient.index.$get as any).mockResolvedValueOnce(createMockResponse(200, {
      data: [
        {
          id: 1,
          name: '北京市',
          code: '110000',
          level: 1,
          parentId: null,
          isDisabled: 0
        }
      ]
    }));

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

    // Check if title is rendered
    expect(screen.getByText('省市区树形管理')).toBeInTheDocument();
    expect(screen.getByText('异步加载树形结构，高效管理省市区数据')).toBeInTheDocument();

    // Wait for loading to complete
    await waitFor(() => {
      expect(screen.getByText('北京市')).toBeInTheDocument();
    });
  });

  it('should show loading state when fetching data', async () => {
    // Mock delayed API response
    (areaClient.index.$get as any).mockImplementationOnce(() =>
      new Promise(resolve => setTimeout(() => resolve(createMockResponse(200, { data: [] })), 100))
    );

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

    // Check if loading state is shown
    expect(screen.getByText('加载中...')).toBeInTheDocument();

    // Wait for loading to complete
    await waitFor(() => {
      expect(screen.queryByText('加载中...')).not.toBeInTheDocument();
    });
  });

  it('should show empty state when no data', async () => {
    // Mock empty API response
    (areaClient.index.$get as any).mockResolvedValueOnce(createMockResponse(200, { data: [] }));

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

    // Wait for empty state to appear
    await waitFor(() => {
      expect(screen.getByText('暂无数据')).toBeInTheDocument();
    });
  });

  it('should open create dialog when clicking add button', async () => {
    // Mock successful API response
    (areaClient.index.$get as any).mockResolvedValueOnce(createMockResponse(200, {
      data: [
        {
          id: 1,
          name: '北京市',
          code: '110000',
          level: 1,
          parentId: null,
          isDisabled: 0
        }
      ]
    }));

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

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

    // Click add button
    const addButton = screen.getByText('新增省');
    fireEvent.click(addButton);

    // Check if dialog opens
    await waitFor(() => {
      expect(screen.getByRole('heading', { name: '新增省' })).toBeInTheDocument();
      expect(screen.getByText('填写省信息')).toBeInTheDocument();
    });
  });

  it('should handle API errors gracefully', async () => {
    // Mock API error
    (areaClient.index.$get as any).mockRejectedValueOnce(new Error('API Error'));

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

    // Wait for error state
    await waitFor(() => {
      // Component should handle errors gracefully
      expect(screen.getByText('省市区树形管理')).toBeInTheDocument();
    });
  });

  it('should complete create and delete workflow', async () => {
    const { toast } = await import('sonner');

    // Mock initial areas data
    const mockAreas = {
      data: [
        {
          id: 1,
          name: '北京市',
          code: '110000',
          level: 1,
          parentId: null,
          isDisabled: 0
        }
      ]
    };

    // Mock initial data fetch
    (areaClient.index.$get as any).mockResolvedValue(createMockResponse(200, mockAreas));

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

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

    // Test create area
    const addButton = screen.getByText('新增省');
    fireEvent.click(addButton);

    // Wait for create dialog
    await waitFor(() => {
      expect(screen.getByRole('heading', { name: '新增省' })).toBeInTheDocument();
    });

    // Fill create form
    const nameInput = screen.getByPlaceholderText('输入区域名称');
    const codeInput = screen.getByPlaceholderText('输入行政区划代码');

    fireEvent.change(nameInput, { target: { value: '上海市' } });
    fireEvent.change(codeInput, { target: { value: '310000' } });

    // Mock successful creation
    (areaClient.index.$post as any).mockResolvedValue(createMockResponse(201, { id: 2, name: '上海市' }));

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

    await waitFor(() => {
      expect(areaClient.index.$post).toHaveBeenCalledWith({
        json: {
          name: '上海市',
          code: '310000',
          level: 1,
          parentId: null,
          isDisabled: 0
        }
      });
      expect(toast.success).toHaveBeenCalledWith('省市区创建成功');
    });

    // 跳过编辑操作测试，专注于创建和删除操作

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

    // Confirm deletion
    expect(screen.getByRole('heading', { name: '确认删除' })).toBeInTheDocument();

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

    // 查找删除确认按钮
    const confirmDeleteButton = screen.getByRole('button', { name: '确认删除' });
    fireEvent.click(confirmDeleteButton);

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

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

    // Mock initial data
    const mockAreas = {
      data: [
        {
          id: 1,
          name: '北京市',
          code: '110000',
          level: 1,
          parentId: null,
          isDisabled: 0
        }
      ]
    };

    (areaClient.index.$get as any).mockResolvedValue(createMockResponse(200, mockAreas));

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

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

    // Test create area error
    const addButton = screen.getByText('新增省');
    fireEvent.click(addButton);

    await waitFor(() => {
      expect(screen.getByRole('heading', { name: '新增省' })).toBeInTheDocument();
    });

    const nameInput = screen.getByPlaceholderText('输入区域名称');
    const codeInput = screen.getByPlaceholderText('输入行政区划代码');

    fireEvent.change(nameInput, { target: { value: '上海市' } });
    fireEvent.change(codeInput, { target: { value: '310000' } });

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

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

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