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 { SystemConfigManagement } from '../../src/components/SystemConfigManagement';
import { systemConfigClientManager } from '../../src/api/systemConfigClient';

// 完整的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/systemConfigClient', () => {
  const mockSystemConfigClient = {
    index: {
      $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
        data: [
          {
            id: 1,
            configKey: 'wx.mini.app.id',
            configValue: 'wx1234567890',
            description: '微信小程序AppID',
            tenantId: 1,
            createdBy: 1,
            updatedBy: 1,
            createdAt: '2024-01-01T00:00:00Z',
            updatedAt: '2024-01-01T00:00:00Z'
          }
        ],
        pagination: {
          page: 1,
          pageSize: 10,
          total: 1,
          totalPages: 1
        }
      }))),
      $post: vi.fn(() => Promise.resolve(createMockResponse(201, { id: 2, configKey: 'wx.mini.app.secret', configValue: 'secret123' }))),
    },
    ':id': {
      $put: vi.fn(() => Promise.resolve(createMockResponse(200, { id: 1, configKey: 'wx.mini.app.id', configValue: 'updated_value' }))),
      $delete: vi.fn(() => Promise.resolve(createMockResponse(204))),
    },
  };

  const mockSystemConfigClientManager = {
    get: vi.fn(() => mockSystemConfigClient),
  };

  return {
    systemConfigClientManager: mockSystemConfigClientManager,
    systemConfigClient: mockSystemConfigClient,
  };
});

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

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

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

describe('系统配置管理集成测试', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('应该完成完整的系统配置CRUD流程', async () => {
    const mockSystemConfigs = {
      data: [
        {
          id: 1,
          configKey: 'wx.mini.app.id',
          configValue: 'wx1234567890',
          description: '微信小程序AppID',
          tenantId: 1,
          createdBy: 1,
          updatedBy: 1,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z'
        },
      ],
      pagination: {
        total: 1,
        page: 1,
        pageSize: 10,
      },
    };

    const { toast } = await import('sonner');

    // Mock initial system config list
    const client = systemConfigClientManager.get();
    (client.index.$get as any).mockResolvedValue({
      ...createMockResponse(200),
      json: async () => mockSystemConfigs
    });

    renderWithProviders(<SystemConfigManagement />);

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

    // Test create system config
    const createButton = screen.getByText('创建配置');
    fireEvent.click(createButton);

    // Fill create form
    const configKeyInput = screen.getByTestId('config-key-input');
    const configValueInput = screen.getByTestId('config-value-input');
    const descriptionInput = screen.getByTestId('description-input');

    fireEvent.change(configKeyInput, { target: { value: 'wx.mini.app.secret' } });
    fireEvent.change(configValueInput, { target: { value: 'secret123' } });
    fireEvent.change(descriptionInput, { target: { value: '微信小程序AppSecret' } });

    // Mock successful creation
    (client.index.$post as any).mockResolvedValue(createMockResponse(201, {
      id: 2,
      configKey: 'wx.mini.app.secret',
      configValue: 'secret123'
    }));

    const submitButton = screen.getByTestId('create-submit-button');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(client.index.$post).toHaveBeenCalledWith({
        json: {
          configKey: 'wx.mini.app.secret',
          configValue: 'secret123',
          description: '微信小程序AppSecret'
        },
      });
      expect(toast.success).toHaveBeenCalledWith('系统配置创建成功');
    });

    // Test edit system config
    const editButton = screen.getByTestId('edit-button-1');
    fireEvent.click(editButton);

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

    // Update system config
    const updateConfigValueInput = screen.getByDisplayValue('wx1234567890');
    fireEvent.change(updateConfigValueInput, { target: { value: 'updated_value' } });

    // Mock successful update
    (client[':id']['$put'] as any).mockResolvedValue(createMockResponse(200));

    const updateButton = screen.getByTestId('update-submit-button');
    fireEvent.click(updateButton);

    await waitFor(() => {
      expect(client[':id']['$put']).toHaveBeenCalledWith({
        param: { id: 1 },
        json: {
          configKey: 'wx.mini.app.id',
          configValue: 'updated_value',
          description: '微信小程序AppID'
        },
      });
      expect(toast.success).toHaveBeenCalledWith('系统配置更新成功');
    });

    // Test delete system config
    const deleteButton = screen.getByTestId('delete-button-1');
    fireEvent.click(deleteButton);

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

    // Mock successful deletion
    (client[':id']['$delete'] as any).mockResolvedValue({
      status: 204,
      ok: true,
      body: null,
      bodyUsed: false,
      statusText: 'No Content',
      headers: new Headers(),
      url: '',
      redirected: false,
      type: 'basic' as ResponseType,
      json: async () => ({}),
      text: async () => '',
      blob: async () => new Blob(),
      arrayBuffer: async () => new ArrayBuffer(0),
      formData: async () => new FormData(),
      clone: function() { return this; }
    });

    const confirmDeleteButton = screen.getByTestId('confirm-delete-button');
    fireEvent.click(confirmDeleteButton);

    await waitFor(() => {
      expect(client[':id']['$delete']).toHaveBeenCalledWith({
        param: { id: 1 },
      });
      expect(toast.success).toHaveBeenCalledWith('系统配置删除成功');
    });
  });

  it('应该优雅处理API错误', async () => {
    const client = systemConfigClientManager.get();
    const { toast } = await import('sonner');

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

    renderWithProviders(<SystemConfigManagement />);

    // Should handle error without crashing
    await waitFor(() => {
      expect(screen.getByText('系统配置管理')).toBeInTheDocument();
    });

    // Test create system config error
    const createButton = screen.getByText('创建配置');
    fireEvent.click(createButton);

    const configKeyInput = screen.getByTestId('config-key-input');
    const configValueInput = screen.getByTestId('config-value-input');

    fireEvent.change(configKeyInput, { target: { value: 'wx.mini.app.id' } });
    fireEvent.change(configValueInput, { target: { value: 'test_value' } });

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

    const submitButton = screen.getByTestId('create-submit-button');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(toast.error).toHaveBeenCalledWith('Creation failed');
    });
  });

  it('应该处理搜索功能', async () => {
    const client = systemConfigClientManager.get();
    const mockSystemConfigs = {
      data: [],
      pagination: { total: 0, page: 1, pageSize: 10 },
    };

    (client.index.$get as any).mockResolvedValue(createMockResponse(200, mockSystemConfigs));

    renderWithProviders(<SystemConfigManagement />);

    // Test search
    const searchInput = screen.getByTestId('search-input');
    fireEvent.change(searchInput, { target: { value: '微信' } });

    const searchButton = screen.getByText('搜索');
    fireEvent.click(searchButton);

    await waitFor(() => {
      expect(client.index.$get).toHaveBeenCalledWith({
        query: {
          page: 1,
          pageSize: 10,
          keyword: '微信',
        },
      });
    });
  });
});