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 { DeliveryAddressManagement } from '../../src/components/DeliveryAddressManagement';
import { deliveryAddressClient, deliveryAddressClientManager } from '../../src/api/deliveryAddressClient';


// 完整的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/deliveryAddressClient', () => {
  const mockDeliveryAddressClient = {
    index: {
      $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
        data: [],
        pagination: { total: 0, current: 1, pageSize: 10 }
      }))),
      $post: vi.fn(() => Promise.resolve(createMockResponse(201, { id: 1, name: '默认地址' }))),
    },
    ':id': {
      $put: vi.fn(() => Promise.resolve(createMockResponse(200))),
      $delete: vi.fn(() => Promise.resolve(createMockResponse(204))),
    },
  };

  const mockDeliveryAddressClientManager = {
    get: vi.fn(() => mockDeliveryAddressClient),
  };

  return {
    deliveryAddressClientManager: mockDeliveryAddressClientManager,
    deliveryAddressClient: mockDeliveryAddressClient,
  };
});

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

// Mock UserSelector (多租户版本)
vi.mock('@d8d/user-management-ui-mt/components', () => ({
  UserSelector: ({ value, onChange, placeholder, 'data-testid': testId }: any) => (
    <select
      data-testid={testId || 'user-selector'}
      value={value || ''}
      onChange={(e) => onChange(e.target.value ? Number(e.target.value) : undefined)}
    >
      <option value="">{placeholder}</option>
      <option value="1">用户1</option>
      <option value="2">用户2</option>
    </select>
  ),
}));

// Mock AreaSelect4Level (多租户版本)
vi.mock('@d8d/area-management-ui-mt/components', () => ({
  AreaSelect4Level: ({
    provinceValue,
    cityValue,
    districtValue,
    townValue,
    onProvinceChange,
    onCityChange,
    onDistrictChange,
    onTownChange,
    showLabels
  }: any) => (
    <div data-testid="area-select-4-level">
      <select
        data-testid="province-select"
        value={provinceValue || 0}
        onChange={(e) => onProvinceChange(Number(e.target.value))}
      >
        <option value={0}>请选择省份</option>
        <option value={1}>北京市</option>
      </select>
      <select
        data-testid="city-select"
        value={cityValue || 0}
        onChange={(e) => onCityChange(Number(e.target.value))}
      >
        <option value={0}>请选择城市</option>
        <option value={2}>北京市</option>
      </select>
      <select
        data-testid="district-select"
        value={districtValue || 0}
        onChange={(e) => onDistrictChange(Number(e.target.value))}
      >
        <option value={0}>请选区县</option>
        <option value={3}>朝阳区</option>
      </select>
      <select
        data-testid="town-select"
        value={townValue || 0}
        onChange={(e) => onTownChange(Number(e.target.value))}
      >
        <option value={0}>请选择乡镇</option>
        <option value={4}>三里屯街道</option>
      </select>
    </div>
  ),
}));

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 mockAddresses = {
      data: [
        {
          id: 1,
          userId: 1,
          name: '张三',
          phone: '13800138000',
          address: '朝阳区三里屯街道',
          receiverProvince: 1,
          receiverCity: 2,
          receiverDistrict: 3,
          receiverTown: 4,
          state: 1,
          isDefault: 1,
          createdBy: 1,
          updatedBy: 1,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
          user: {
            id: 1,
            name: 'user1',
            phone: '13800138000',
          },
          province: {
            id: 1,
            name: '北京市',
          },
          city: {
            id: 2,
            name: '北京市',
          },
          district: {
            id: 3,
            name: '朝阳区',
          },
          town: {
            id: 4,
            name: '三里屯街道',
          },
        },
      ],
      pagination: {
        total: 1,
        current: 1,
        pageSize: 10,
      },
    };

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

    // Mock initial address list
    (deliveryAddressClient.index.$get as any).mockResolvedValue(createMockResponse(200, mockAddresses));

    renderWithProviders(<DeliveryAddressManagement />);

    // Wait for initial data to load
    await waitFor(() => {
      expect(screen.getByTestId('address-name-1')).toHaveTextContent('张三');
    });

    // Test create address
    const createButton = screen.getByText('创建收货地址');
    fireEvent.click(createButton);

    // Fill create form
    const nameInput = screen.getByPlaceholderText('请输入收货人姓名');
    const phoneInput = screen.getByPlaceholderText('请输入手机号');
    const addressInput = screen.getByPlaceholderText('请输入详细地址');

    fireEvent.change(nameInput, { target: { value: '李四' } });
    fireEvent.change(phoneInput, { target: { value: '13900139000' } });
    fireEvent.change(addressInput, { target: { value: '详细地址信息' } });

    // Select user
    const userSelector = screen.getByTestId('create-user-selector');
    fireEvent.change(userSelector, { target: { value: '1' } });

    // Select area
    const provinceSelect = screen.getByTestId('province-select');
    fireEvent.change(provinceSelect, { target: { value: '1' } });

    const citySelect = screen.getByTestId('city-select');
    fireEvent.change(citySelect, { target: { value: '2' } });

    const districtSelect = screen.getByTestId('district-select');
    fireEvent.change(districtSelect, { target: { value: '3' } });

    const townSelect = screen.getByTestId('town-select');
    fireEvent.change(townSelect, { target: { value: '4' } });

    // Mock successful creation
    (deliveryAddressClient.index.$post as any).mockResolvedValue(createMockResponse(201, { id: 2, name: '李四' }));

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

    await waitFor(() => {
      expect(deliveryAddressClientManager.get().index.$post).toHaveBeenCalledWith({
        json: {
          userId: 1,
          name: '李四',
          phone: '13900139000',
          address: '详细地址信息',
          receiverProvince: 1,
          receiverCity: 2,
          receiverDistrict: 3,
          receiverTown: 4,
          isDefault: 0,
        },
      });
      expect(toast.success).toHaveBeenCalledWith('收货地址创建成功');
    });

    // Test edit address
    const editButtons = screen.getAllByTestId('edit-address-button');
    fireEvent.click(editButtons[0]);

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

    // Update address
    const updateNameInput = screen.getByDisplayValue('张三');
    fireEvent.change(updateNameInput, { target: { value: '王五' } });

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

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

    await waitFor(() => {
      expect(deliveryAddressClientManager.get()[':id']['$put']).toHaveBeenCalledWith({
        param: { id: 1 },
        json: {
          name: '王五',
          phone: '13800138000',
          address: '朝阳区三里屯街道',
          receiverProvince: 1,
          receiverCity: 2,
          receiverDistrict: 3,
          receiverTown: 4,
          isDefault: 1,
        },
      });
      expect(toast.success).toHaveBeenCalledWith('收货地址更新成功');
    });

    // Test delete address
    const deleteButtons = screen.getAllByTestId('delete-address-button');
    fireEvent.click(deleteButtons[0]);

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

    // Mock successful deletion
    (deliveryAddressClient[':id']['$delete'] as any).mockResolvedValue(createMockResponse(204));

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

    await waitFor(() => {
      expect(deliveryAddressClientManager.get()[':id']['$delete']).toHaveBeenCalledWith({
        param: { id: 1 },
      });
      expect(toast.success).toHaveBeenCalledWith('收货地址删除成功');
    });
  });

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

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

    renderWithProviders(<DeliveryAddressManagement />);

    // Should handle error without crashing
    await waitFor(() => {
      expect(screen.getByText('用户收货地址')).toBeInTheDocument();
    });

    // Test create address error
    const createButton = screen.getByText('创建收货地址');
    fireEvent.click(createButton);

    // Fill all required fields
    const userSelector = screen.getByTestId('create-user-selector');
    const nameInput = screen.getByPlaceholderText('请输入收货人姓名');
    const phoneInput = screen.getByPlaceholderText('请输入手机号');
    const addressInput = screen.getByPlaceholderText('请输入详细地址');

    fireEvent.change(userSelector, { target: { value: '1' } });
    fireEvent.change(nameInput, { target: { value: '测试用户' } });
    fireEvent.change(phoneInput, { target: { value: '13800138000' } });
    fireEvent.change(addressInput, { target: { value: '详细地址信息' } });

    // Area values are set with default 0 values which should pass validation

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

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

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

  it('应该处理搜索和过滤器集成', async () => {
    const mockAddresses = {
      data: [],
      pagination: {
        total: 0,
        current: 1,
        pageSize: 10,
      },
    };

    (deliveryAddressClient.index.$get as any).mockResolvedValue(createMockResponse(200, mockAddresses));

    renderWithProviders(<DeliveryAddressManagement />);

    // Test search
    const searchInput = screen.getByPlaceholderText('搜索姓名、手机号、地址...');
    fireEvent.change(searchInput, { target: { value: '张三' } });

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

    // Test user filter
    const userSelector = screen.getByTestId('search-user-selector');
    fireEvent.change(userSelector, { target: { value: '1' } });

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

    await waitFor(() => {
      expect(deliveryAddressClientManager.get().index.$get).toHaveBeenCalledWith({
        query: {
          page: 1,
          pageSize: 10,
          keyword: '张三',
          userId: 1,
        },
      });
    });
  });

  it('应该正确显示地址状态和默认地址标记', async () => {
    const mockAddresses = {
      data: [
        {
          id: 1,
          userId: 1,
          name: '张三',
          phone: '13800138000',
          address: '朝阳区三里屯街道',
          receiverProvince: 1,
          receiverCity: 2,
          receiverDistrict: 3,
          receiverTown: 4,
          state: 1,
          isDefault: 1,
          createdBy: 1,
          updatedBy: 1,
          createdAt: '2024-01-01T00:00:00Z',
          updatedAt: '2024-01-01T00:00:00Z',
          user: {
            id: 1,
            name: 'user1',
            phone: '13800138000',
          },
        },
      ],
      pagination: {
        total: 1,
        current: 1,
        pageSize: 10,
      },
    };

    (deliveryAddressClient.index.$get as any).mockResolvedValue(createMockResponse(200, mockAddresses));

    renderWithProviders(<DeliveryAddressManagement />);

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

    // Debug: check if table rows are rendered
    const tableRows = screen.queryAllByRole('row');
    console.log('Table rows found:', tableRows.length);

    // Debug: check if data cells are rendered
    const dataCells = screen.queryAllByRole('cell');
    console.log('Data cells found:', dataCells.length);

    // Debug: check if badges are rendered
    const badges = screen.queryAllByTestId(/status-|is-default-/);
    console.log('Badges found:', badges.length);
    badges.forEach((badge, index) => {
      console.log(`Badge ${index}:`, badge.getAttribute('data-testid'));
    });

    // Verify status badges
    expect(screen.getByTestId('status-active')).toBeInTheDocument();
    expect(screen.getByTestId('is-default-true')).toBeInTheDocument();
  });
});