import React from 'react'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import AddressManagePage from '@/pages/address-manage/index'

// 导入Taro mock函数
import { mockGetCurrentPages, mockNavigateTo, mockShowModal } from '~/__mocks__/taroMock'

// Mock API client
jest.mock('@/api', () => ({
  deliveryAddressClient: {
    $get: jest.fn(),
    $post: jest.fn(),
    ':id': {
      $put: jest.fn(),
      $delete: jest.fn(),
      'set-default': {
        $post: jest.fn(),
      },
    },
  },
}))

// Mock auth hook
jest.mock('@/utils/auth', () => ({
  useAuth: () => ({
    user: { id: 1 },
  }),
}))

// Mock components
jest.mock('@/components/ui/navbar', () => ({
  Navbar: ({ title, onClickLeft }: { title: string; onClickLeft: () => void }) => (
    <div data-testid="navbar">
      <span>{title}</span>
      <button onClick={onClickLeft}>返回</button>
    </div>
  ),
}))

jest.mock('@/components/ui/button', () => ({
  Button: ({ children, onClick, disabled, className }: any) => (
    <button
      onClick={onClick}
      disabled={disabled}
      className={className}
      data-testid="button"
    >
      {children}
    </button>
  ),
}))

describe('AddressManagePage', () => {
  let queryClient: QueryClient

  beforeEach(() => {
    queryClient = new QueryClient({
      defaultOptions: {
        queries: { retry: false },
        mutations: { retry: false },
      },
    })

    // Reset all mocks
    jest.clearAllMocks()

    // 设置 getCurrentPages 的默认返回值
    mockGetCurrentPages.mockReturnValue([{ route: 'pages/address-manage/index' }])
  })

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

  const mockAddresses = [
    {
      id: 1,
      name: '张三',
      phone: '13812345678',
      province: { name: '广东省' },
      city: { name: '深圳市' },
      district: { name: '南山区' },
      town: { name: '科技园' },
      address: '科技大厦A座',
      isDefault: 1,
    },
    {
      id: 2,
      name: '李四',
      phone: '13987654321',
      province: { name: '北京市' },
      city: { name: '北京市' },
      district: { name: '朝阳区' },
      town: { name: '' },
      address: '国贸中心',
      isDefault: 0,
    },
  ]

  it('渲染页面标题和布局', async () => {
    const { deliveryAddressClient } = await import('@/api')
    ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({
      status: 200,
      json: async () => ({ data: [] }),
    } as any)

    renderWithProviders(<AddressManagePage />)

    expect(screen.getByTestId('navbar')).toBeInTheDocument()
    expect(screen.getByText('收货地址')).toBeInTheDocument()
  })

  it('显示地址列表', async () => {
    const { deliveryAddressClient } = await import('@/api')
    ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({
      status: 200,
      json: async () => ({ data: mockAddresses }),
    } as any)

    renderWithProviders(<AddressManagePage />)

    await waitFor(() => {
      expect(screen.getByText('张三')).toBeInTheDocument()
      expect(screen.getByText('李四')).toBeInTheDocument()
      expect(screen.getByText('138****5678')).toBeInTheDocument()
      expect(screen.getByText('139****4321')).toBeInTheDocument()
      expect(screen.getByText('默认')).toBeInTheDocument()
    })
  })

  it('显示空状态', async () => {
    const { deliveryAddressClient } = await import('@/api')
    ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({
      status: 200,
      json: async () => ({ data: [] }),
    } as any)

    renderWithProviders(<AddressManagePage />)

    await waitFor(() => {
      expect(screen.getByText('暂无收货地址')).toBeInTheDocument()
    })
  })

  it('显示地址数量限制提示', async () => {
    const { deliveryAddressClient } = await import('@/api')
    const addresses = Array.from({ length: 20 }, (_, i) => ({
      id: i + 1,
      name: `用户${i + 1}`,
      phone: '13812345678',
      province: { name: '广东省' },
      city: { name: '深圳市' },
      district: { name: '南山区' },
      address: '测试地址',
      isDefault: i === 0 ? 1 : 0,
    }))

    ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({
      status: 200,
      json: async () => ({ data: addresses }),
    } as any)

    renderWithProviders(<AddressManagePage />)

    await waitFor(() => {
      expect(screen.getByText('最多可添加20个收货地址')).toBeInTheDocument()
    })
  })

  it('点击添加地址按钮', async () => {
    const { deliveryAddressClient } = await import('@/api')
    ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({
      status: 200,
      json: async () => ({ data: [] }),
    } as any)

    renderWithProviders(<AddressManagePage />)

    await waitFor(() => {
      const addButton = screen.getByText('添加新地址')
      fireEvent.click(addButton)
      expect(mockNavigateTo).toHaveBeenCalledWith({
        url: '/pages/address-edit/index',
      })
    })
  })

  it('点击编辑地址按钮', async () => {
    const { deliveryAddressClient } = await import('@/api')
    ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({
      status: 200,
      json: async () => ({ data: mockAddresses }),
    } as any)

    renderWithProviders(<AddressManagePage />)

    await waitFor(() => {
      const editButtons = screen.getAllByText('编辑')
      fireEvent.click(editButtons[0])
      expect(mockNavigateTo).toHaveBeenCalledWith({
        url: '/pages/address-edit/index?id=1',
      })
    })
  })

  it('点击设为默认按钮', async () => {
    const { deliveryAddressClient } = await import('@/api')
    ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({
      status: 200,
      json: async () => ({ data: mockAddresses }),
    } as any)

    ;(deliveryAddressClient[':id'].$put as jest.Mock).mockResolvedValue({
      status: 200,
      json: async () => ({}),
    } as any)

    renderWithProviders(<AddressManagePage />)

    await waitFor(() => {
      const setDefaultButtons = screen.getAllByText('设为默认')
      fireEvent.click(setDefaultButtons[0])
      expect(deliveryAddressClient[':id'].$put).toHaveBeenCalledWith({
        param: { id: 2 },
        json: { isDefault: 1 },
      })
    })
  })

  it('点击删除按钮', async () => {
    const { deliveryAddressClient } = await import('@/api')
    ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({
      status: 200,
      json: async () => ({ data: mockAddresses }),
    } as any)

    ;(deliveryAddressClient[':id'].$delete as jest.Mock).mockResolvedValue({
      status: 204,
      json: async () => ({}),
    } as any)

    renderWithProviders(<AddressManagePage />)

    await waitFor(() => {
      const deleteButtons = screen.getAllByText('删除')
      fireEvent.click(deleteButtons[0])
      expect(mockShowModal).toHaveBeenCalled()
    })
  })

  it('验证样式类名应用', async () => {
    const { deliveryAddressClient } = await import('@/api')
    ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({
      status: 200,
      json: async () => ({ data: mockAddresses }),
    } as any)

    renderWithProviders(<AddressManagePage />)

    await waitFor(() => {
      const container = document.querySelector('.address-container')
      expect(container).toBeInTheDocument()

      const addressList = document.querySelector('.address-list')
      expect(addressList).toBeInTheDocument()

      const addressItems = document.querySelectorAll('.address-item')
      expect(addressItems).toHaveLength(2)

      const bottomFixed = document.querySelector('.bottom-fixed')
      expect(bottomFixed).toBeInTheDocument()
    })
  })
})