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 { PrintConfigManagement } from '../../src/components/PrintConfigManagement';
import { createFeiePrinterClient } from '../../src/api/feiePrinterClient';
import { ConfigKey, ConfigType } from '../../src/types/feiePrinter';

// Mock API client
vi.mock('../../src/api/feiePrinterClient', () => {
  const mockClient = {
    getPrintConfigs: vi.fn(),
    updatePrintConfig: vi.fn(),
    setAuthToken: vi.fn(),
    setTenantId: vi.fn(),
  };

  return {
    createFeiePrinterClient: vi.fn(() => mockClient),
  };
});

// Mock toast
vi.mock('sonner', () => ({
  toast: {
    success: vi.fn(() => {}),
    error: vi.fn(() => {}),
    info: 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('打印配置管理组件集成测试', () => {
  let mockClient: any;

  beforeEach(() => {
    vi.clearAllMocks();
    mockClient = (createFeiePrinterClient as any)();
  });

  it('应该渲染组件并加载配置数据', async () => {
    const mockConfigsData = {
      data: [
        {
          id: 1,
          configKey: ConfigKey.ANTI_REFUND_DELAY,
          configValue: '120',
          configType: ConfigType.NUMBER,
          description: '防退款延迟时间（秒）',
          isEnabled: 1,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
        },
      ],
      pagination: {
        total: 1,
        page: 1,
        pageSize: 20,
        totalPages: 1,
      },
    };

    // Mock initial configs data
    mockClient.getPrintConfigs.mockResolvedValue(mockConfigsData);

    renderWithProviders(
      <PrintConfigManagement
        baseURL="/api/v1/feie"
        tenantId={123}
        authToken="test-token"
      />
    );

    // 验证API被调用
    await waitFor(() => {
      expect(mockClient.getPrintConfigs).toHaveBeenCalled();
    });

    // 验证组件标题渲染
    expect(screen.getByText('打印配置管理')).toBeInTheDocument();
    expect(screen.getByText('管理飞鹅打印的配置项，包括基础配置、打印策略和模板配置')).toBeInTheDocument();

    // 验证刷新按钮存在
    expect(screen.getByRole('button', { name: /刷新/i })).toBeInTheDocument();
  });

  it('应该处理获取配置列表API错误', async () => {
    // Mock API error
    mockClient.getPrintConfigs.mockRejectedValue(new Error('获取配置列表失败'));

    renderWithProviders(
      <PrintConfigManagement
        baseURL="/api/v1/feie"
        tenantId={123}
        authToken="test-token"
      />
    );

    // 检查错误UI是否显示
    await waitFor(() => {
      expect(screen.getByText('加载配置失败')).toBeInTheDocument();
      expect(screen.getByRole('button', { name: /重试/i })).toBeInTheDocument();
    });
  });

  it('应该处理更新配置API错误', async () => {
    const { toast } = await import('sonner');

    const mockConfigsData = {
      data: [
        {
          id: 1,
          configKey: ConfigKey.ANTI_REFUND_DELAY,
          configValue: '120',
          configType: ConfigType.NUMBER,
          description: '防退款延迟时间（秒）',
          isEnabled: 1,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
        },
      ],
      pagination: {
        total: 1,
        page: 1,
        pageSize: 20,
        totalPages: 1,
      },
    };

    mockClient.getPrintConfigs.mockResolvedValue(mockConfigsData);
    mockClient.updatePrintConfig.mockRejectedValue(new Error('更新配置失败'));

    renderWithProviders(
      <PrintConfigManagement
        baseURL="/api/v1/feie"
        tenantId={123}
        authToken="test-token"
      />
    );

    // 等待初始数据加载
    await waitFor(() => {
      expect(mockClient.getPrintConfigs).toHaveBeenCalled();
    });

    // 等待配置项渲染
    await waitFor(() => {
      expect(screen.getByText('防退款延迟时间（秒）')).toBeInTheDocument();
    });

    // 找到配置值输入框（根据组件行为，可能是spinbutton或textbox）
    // 注意：实际组件可能使用不同的输入方式，这里需要根据实际组件调整
    let configInputs = screen.queryAllByRole('spinbutton');
    if (configInputs.length === 0) {
      configInputs = screen.queryAllByRole('textbox');
    }
    expect(configInputs.length).toBeGreaterThan(0);

    // 修改配置值
    fireEvent.change(configInputs[0], { target: { value: '180' } });

    // 找到批量保存按钮
    const saveButtons = screen.getAllByRole('button', { name: /批量保存/i });
    expect(saveButtons.length).toBeGreaterThan(0);

    // 点击批量保存按钮
    fireEvent.click(saveButtons[0]);

    await waitFor(() => {
      expect(toast.error).toHaveBeenCalledWith('批量保存失败: 更新配置失败');
    });
  });

  it('应该支持多租户场景', async () => {
    const mockConfigsData = {
      data: [
        {
          id: 1,
          configKey: ConfigKey.ANTI_REFUND_DELAY,
          configValue: '150',
          configType: ConfigType.NUMBER,
          description: '防退款延迟时间（秒）',
          isEnabled: 1,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
        },
      ],
      pagination: {
        total: 1,
        page: 1,
        pageSize: 20,
        totalPages: 1,
      },
    };

    mockClient.getPrintConfigs.mockResolvedValue(mockConfigsData);

    renderWithProviders(
      <PrintConfigManagement
        baseURL="/api/v1/feie"
        tenantId={456}
        authToken="test-token"
      />
    );

    await waitFor(() => {
      expect(mockClient.getPrintConfigs).toHaveBeenCalled();
    });

    // 验证租户ID设置
    expect(mockClient.setTenantId).toHaveBeenCalledWith(456);
    expect(mockClient.setAuthToken).toHaveBeenCalledWith('test-token');

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByText('防退款延迟时间（秒）')).toBeInTheDocument();
    });

    // 配置值在输入框中，检查输入框存在
    const configInputs = screen.queryAllByRole('spinbutton');
    const textInputs = screen.queryAllByRole('textbox');
    expect(configInputs.length + textInputs.length).toBeGreaterThan(0);

    // 检查租户ID设置是否正确
    expect(mockClient.setTenantId).toHaveBeenCalledWith(456);
    expect(mockClient.setAuthToken).toHaveBeenCalledWith('test-token');
  });

  it('应该处理配置项启用/禁用状态', async () => {
    const mockConfigsData = {
      data: [
        {
          id: 1,
          configKey: ConfigKey.ANTI_REFUND_DELAY,
          configValue: '120',
          configType: ConfigType.NUMBER,
          description: '防退款延迟时间（秒）',
          isEnabled: 1,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
        },
        {
          id: 2,
          configKey: ConfigKey.RECEIPT_TEMPLATE,
          configValue: '订单号: {orderNo}',
          configType: ConfigType.STRING,
          description: '小票模板',
          isEnabled: 0, // 禁用状态
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00Z',
        },
      ],
      pagination: {
        total: 2,
        page: 1,
        pageSize: 20,
        totalPages: 1,
      },
    };

    mockClient.getPrintConfigs.mockResolvedValue(mockConfigsData);

    renderWithProviders(
      <PrintConfigManagement
        baseURL="/api/v1/feie"
        tenantId={123}
        authToken="test-token"
      />
    );

    // 等待数据加载 - 至少检查一个配置项存在
    await waitFor(() => {
      expect(screen.getByText('防退款延迟时间（秒）')).toBeInTheDocument();
    });

    // 检查组件基本渲染
    expect(screen.getByText('打印配置管理')).toBeInTheDocument();
    expect(screen.getByRole('button', { name: /刷新/i })).toBeInTheDocument();
  });

  it('应该处理不同配置类型的显示', async () => {
    const mockConfigsData = {
      data: [
        {
          id: 1,
          configKey: ConfigKey.ANTI_REFUND_DELAY,
          configValue: '120',
          configType: ConfigType.NUMBER,
          description: '防退款延迟时间（秒）',
          isEnabled: 1,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
        },
        {
          id: 2,
          configKey: ConfigKey.RECEIPT_TEMPLATE,
          configValue: '订单号: {orderNo}',
          configType: ConfigType.STRING,
          description: '小票模板',
          isEnabled: 1,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
        },
        {
          id: 3,
          configKey: ConfigKey.SHIPPING_TEMPLATE,
          configValue: '发货单\n订单号: {orderNo}',
          configType: ConfigType.STRING,
          description: '发货单模板',
          isEnabled: 1,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
        },
      ],
      pagination: {
        total: 3,
        page: 1,
        pageSize: 20,
        totalPages: 1,
      },
    };

    mockClient.getPrintConfigs.mockResolvedValue(mockConfigsData);

    renderWithProviders(
      <PrintConfigManagement
        baseURL="/api/v1/feie"
        tenantId={123}
        authToken="test-token"
      />
    );

    // 等待数据加载 - 至少检查一个配置项存在
    await waitFor(() => {
      expect(screen.getByText('防退款延迟时间（秒）')).toBeInTheDocument();
    });

    // 检查组件基本渲染和输入框存在
    expect(screen.getByText('打印配置管理')).toBeInTheDocument();

    // 检查是否有输入框（配置值在输入框中）
    const configInputs = screen.queryAllByRole('spinbutton');
    const textInputs = screen.queryAllByRole('textbox');
    expect(configInputs.length + textInputs.length).toBeGreaterThan(0);
  });
});