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 ChannelManagement from '../../src/components/ChannelManagement';
import { channelClientManager } from '../../src/api/channelClient';

// 完整的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/channelClient', () => {
  const mockChannelClient = {
    getAllChannels: {
      $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
        data: [
          {
            id: 1,
            channelName: '微信小程序',
            channelType: '小程序',
            contactPerson: '张三',
            contactPhone: '13800138000',
            description: '微信小程序渠道',
            status: 1,
            createTime: '2024-01-01T00:00:00Z',
            updateTime: '2024-01-01T00:00:00Z'
          },
          {
            id: 2,
            channelName: '支付宝生活号',
            channelType: '生活号',
            contactPerson: '李四',
            contactPhone: '13900139000',
            description: '支付宝生活号渠道',
            status: 1,
            createTime: '2024-01-02T00:00:00Z',
            updateTime: '2024-01-02T00:00:00Z'
          }
        ],
        total: 2
      }))),
    },
    createChannel: {
      $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
        id: 3,
        channelName: '抖音小程序',
        channelType: '小程序',
        contactPerson: '王五',
        contactPhone: '13700137000',
        description: '抖音小程序渠道',
        status: 1
      }))),
    },
    updateChannel: {
      $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
        id: 1,
        channelName: '更新后的微信小程序',
        channelType: '小程序',
        contactPerson: '张三',
        contactPhone: '13800138000',
        description: '更新后的微信小程序渠道',
        status: 1
      }))),
    },
    deleteChannel: {
      $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
        success: true
      }))),
    },
    searchChannels: {
      $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
        data: [
          {
            id: 1,
            channelName: '微信小程序',
            channelType: '小程序',
            contactPerson: '张三',
            contactPhone: '13800138000',
            description: '微信小程序渠道',
            status: 1,
            createTime: '2024-01-01T00:00:00Z',
            updateTime: '2024-01-01T00:00:00Z'
          }
        ],
        total: 1
      }))),
    },
    getChannel: {
      ':id': {
        $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
          id: 1,
          channelName: '微信小程序',
          channelType: '小程序',
          contactPerson: '张三',
          contactPhone: '13800138000',
          description: '微信小程序渠道',
          status: 1,
          createTime: '2024-01-01T00:00:00Z',
          updateTime: '2024-01-01T00:00:00Z'
        }))),
      }
    },
    // 注意：渠道模块使用自定义路由，没有batchDeleteChannel路由
  };

  const mockChannelClientManager = {
    get: vi.fn(() => mockChannelClient),
  };

  return {
    channelClientManager: mockChannelClientManager,
    channelClient: mockChannelClient,
  };
});

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

describe('ChannelManagement 集成测试', () => {
  let queryClient: QueryClient;

  beforeEach(() => {
    queryClient = new QueryClient({
      defaultOptions: {
        queries: {
          retry: false,
        },
      },
    });
    vi.clearAllMocks();
  });

  const renderComponent = () => {
    return render(
      <QueryClientProvider client={queryClient}>
        <ChannelManagement />
      </QueryClientProvider>
    );
  };

  it('应该正确渲染渠道列表', async () => {
    renderComponent();

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByText('微信小程序')).toBeInTheDocument();
    });

    // 验证表格内容
    expect(screen.getByText('支付宝生活号')).toBeInTheDocument();
    expect(screen.getByText('张三')).toBeInTheDocument();
    expect(screen.getByText('13800138000')).toBeInTheDocument();
    expect(screen.getByText('小程序')).toBeInTheDocument();
    expect(screen.getByText('生活号')).toBeInTheDocument();
  });

  it('应该打开创建渠道模态框', async () => {
    renderComponent();

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByText('微信小程序')).toBeInTheDocument();
    });

    // 点击创建按钮
    const createButton = screen.getByTestId('create-channel-button');
    fireEvent.click(createButton);

    // 验证模态框打开
    expect(screen.getByTestId('create-channel-modal-title')).toBeInTheDocument();
  });

  it('应该成功创建渠道', async () => {
    renderComponent();

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByText('微信小程序')).toBeInTheDocument();
    });

    // 打开创建模态框
    const createButton = screen.getByTestId('create-channel-button');
    fireEvent.click(createButton);

    // 填写表单
    const channelNameInput = screen.getByLabelText('渠道名称 *');
    const channelTypeInput = screen.getByLabelText('渠道类型');
    const contactPersonInput = screen.getByLabelText('联系人');
    const contactPhoneInput = screen.getByLabelText('联系电话');
    const descriptionInput = screen.getByLabelText('描述');

    fireEvent.change(channelNameInput, { target: { value: '抖音小程序' } });
    fireEvent.change(channelTypeInput, { target: { value: '小程序' } });
    fireEvent.change(contactPersonInput, { target: { value: '王五' } });
    fireEvent.change(contactPhoneInput, { target: { value: '13700137000' } });
    fireEvent.change(descriptionInput, { target: { value: '抖音小程序渠道' } });

    // 提交表单
    const submitButton = screen.getByText('创建');
    fireEvent.click(submitButton);

    // 验证API调用
    await waitFor(() => {
      expect(channelClientManager.get().createChannel.$post).toHaveBeenCalledWith({
        json: {
          channelName: '抖音小程序',
          channelType: '小程序',
          contactPerson: '王五',
          contactPhone: '13700137000',
          description: '抖音小程序渠道'
        }
      });
    });
  });

  it('应该打开编辑渠道模态框', async () => {
    renderComponent();

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByText('微信小程序')).toBeInTheDocument();
    });

    // 点击编辑按钮
    const editButton = screen.getByTestId('edit-channel-1');
    fireEvent.click(editButton);

    // 验证模态框打开并显示正确的数据
    expect(screen.getByTestId('create-channel-modal-title')).toBeInTheDocument();
    expect(screen.getByDisplayValue('微信小程序')).toBeInTheDocument();
  });

  it('应该成功更新渠道', async () => {
    renderComponent();

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByText('微信小程序')).toBeInTheDocument();
    });

    // 打开编辑模态框
    const editButton = screen.getByTestId('edit-channel-1');
    fireEvent.click(editButton);

    // 修改表单数据
    const channelNameInput = screen.getByLabelText('渠道名称 *');
    fireEvent.change(channelNameInput, { target: { value: '更新后的微信小程序' } });

    // 提交表单
    const submitButton = screen.getByText('更新');
    fireEvent.click(submitButton);

    // 验证API调用
    await waitFor(() => {
      expect(channelClientManager.get().updateChannel.$post).toHaveBeenCalledWith({
        json: {
          id: 1,
          channelName: '更新后的微信小程序',
          channelType: '小程序',
          contactPerson: '张三',
          contactPhone: '13800138000',
          description: '微信小程序渠道'
        }
      });
    });
  });

  it('应该打开删除确认对话框', async () => {
    renderComponent();

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByText('微信小程序')).toBeInTheDocument();
    });

    // 点击删除按钮
    const deleteButton = screen.getByTestId('delete-channel-1');
    fireEvent.click(deleteButton);

    // 验证删除确认对话框打开
    expect(screen.getByTestId('delete-confirm-dialog-title')).toBeInTheDocument();
  });

  it('应该成功搜索渠道', async () => {
    renderComponent();

    // 等待数据加载
    await waitFor(() => {
      expect(screen.getByText('微信小程序')).toBeInTheDocument();
    });

    // 输入搜索关键词
    const searchInput = screen.getByTestId('search-input');
    fireEvent.change(searchInput, { target: { value: '微信' } });

    // 点击搜索按钮
    const searchButton = screen.getByTestId('search-button');
    fireEvent.click(searchButton);

    // 验证API调用
    await waitFor(() => {
      expect(channelClientManager.get().searchChannels.$get).toHaveBeenCalledWith({
        query: {
          name: '微信',
          skip: 0,
          take: 10
        }
      });
    });
  });

  it('应该处理API错误', async () => {
    // Mock API错误 - 使用vi.spyOn来mock
    const mockErrorResponse = createMockResponse(500, { message: '服务器错误' });
    vi.spyOn(channelClientManager.get().getAllChannels, '$get').mockResolvedValue(mockErrorResponse as any);

    renderComponent();

    // 验证错误处理 - 等待错误状态
    await waitFor(() => {
      // 检查是否没有显示数据
      expect(screen.queryByText('微信小程序')).not.toBeInTheDocument();
      expect(screen.queryByText('支付宝生活号')).not.toBeInTheDocument();
    });

    // 恢复原始mock
    vi.mocked(channelClientManager.get().getAllChannels.$get).mockRestore();
  });
});