import React from 'react'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import ActivitySelectPage from '../../src/pages/select-activity/ActivitySelectPage'

// 导入 Taro mock 函数
import taroMock, { mockUseRouter, mockNavigateBack } from '../__mocks__/taroMock'

// Mock API 客户端
let mockRouteClient: any

jest.mock('../../src/api', () => {
  mockRouteClient = {
    search: {
      $get: jest.fn()
    }
  }

  return {
    routeClient: mockRouteClient
  }
})

// Mock Navbar 组件
jest.mock('@/components/ui/navbar', () => ({
  Navbar: jest.fn(({ title, leftIcon, onClickLeft, ...props }) => (
    <div data-testid="navbar">
      <div data-testid="navbar-title">{title}</div>
      <button data-testid="navbar-back" onClick={onClickLeft}>返回</button>
    </div>
  )),
  NavbarPresets: {
    primary: {}
  }
}))

// 创建测试用的 QueryClient
const createTestQueryClient = () => new QueryClient({
  defaultOptions: {
    queries: {
      retry: false,
    },
  },
})

// 包装组件
const Wrapper = ({ children }: { children: React.ReactNode }) => {
  const queryClient = createTestQueryClient()
  return (
    <QueryClientProvider client={queryClient}>
      {children}
    </QueryClientProvider>
  )
}

// 模拟活动数据
const mockActivities = [
  {
    id: 1,
    name: '音乐节活动',
    description: '大型音乐节活动',
    startDate: '2025-11-01T10:00:00Z',
    endDate: '2025-11-01T22:00:00Z',
    venueLocationId: 1,
    venueLocation: {
      id: 1,
      name: '北京工人体育场',
      provinceId: 1,
      cityId: 11,
      districtId: 101,
      address: '北京市朝阳区工人体育场北路',
      latitude: '39.929985',
      longitude: '116.395645',
      province: {
        id: 1,
        name: '北京市',
        level: 1,
        code: '110000'
      },
      city: {
        id: 11,
        name: '北京市',
        level: 2,
        code: '110100'
      },
      district: {
        id: 101,
        name: '朝阳区',
        level: 3,
        code: '110105'
      }
    }
  },
  {
    id: 2,
    name: '体育赛事',
    description: '足球比赛',
    startDate: '2025-11-02T15:00:00Z',
    endDate: '2025-11-02T17:00:00Z',
    venueLocationId: 2,
    venueLocation: {
      id: 2,
      name: '上海体育场',
      provinceId: 2,
      cityId: 22,
      districtId: 202,
      address: '上海市徐汇区天钥桥路666号',
      latitude: '31.230416',
      longitude: '121.473701',
      province: {
        id: 2,
        name: '上海市',
        level: 1,
        code: '310000'
      },
      city: {
        id: 22,
        name: '上海市',
        level: 2,
        code: '310100'
      },
      district: {
        id: 202,
        name: '徐汇区',
        level: 3,
        code: '310104'
      }
    }
  }
]

// 模拟路线数据
const mockRoutes = [
  {
    id: 1,
    activityId: 1,
    routeType: 'departure',
    startLocation: {
      id: 1,
      name: '北京南站',
      provinceId: 1,
      cityId: 11,
      districtId: 101,
      province: { id: 1, name: '北京市' },
      city: { id: 11, name: '北京市' },
      district: { id: 101, name: '朝阳区' }
    },
    endLocation: {
      id: 2,
      name: '上海虹桥站',
      provinceId: 2,
      cityId: 22,
      districtId: 202,
      province: { id: 2, name: '上海市' },
      city: { id: 22, name: '上海市' },
      district: { id: 202, name: '徐汇区' }
    }
  },
  {
    id: 2,
    activityId: 2,
    routeType: 'return',
    startLocation: {
      id: 2,
      name: '上海虹桥站',
      provinceId: 2,
      cityId: 22,
      districtId: 202,
      province: { id: 2, name: '上海市' },
      city: { id: 22, name: '上海市' },
      district: { id: 202, name: '徐汇区' }
    },
    endLocation: {
      id: 1,
      name: '北京南站',
      provinceId: 1,
      cityId: 11,
      districtId: 101,
      province: { id: 1, name: '北京市' },
      city: { id: 11, name: '北京市' },
      district: { id: 101, name: '朝阳区' }
    }
  }
]

describe('活动选择页面测试', () => {
  beforeEach(() => {
    jest.clearAllMocks()

    // 设置默认的路由参数
    mockUseRouter.mockReturnValue({
      params: {
        startAreaIds: JSON.stringify([1, 11, 101]),
        endAreaIds: JSON.stringify([2, 22, 202]),
        startAreaName: encodeURIComponent('北京市 北京市 朝阳区'),
        endAreaName: encodeURIComponent('上海市 上海市 徐汇区'),
        date: '2025-11-01',
        vehicleType: 'bus',
        travelMode: 'carpool'
      }
    })

    // 设置默认的API响应
    mockRouteClient.search.$get.mockResolvedValue({
      status: 200,
      json: async () => ({
        success: true,
        data: {
          routes: mockRoutes,
          activities: mockActivities
        }
      })
    })
  })

  test('应该正确渲染活动选择页面', async () => {
    render(
      <Wrapper>
        <ActivitySelectPage />
      </Wrapper>
    )

    // 检查导航栏
    await waitFor(() => {
      expect(screen.getByTestId('navbar')).toBeInTheDocument()
      expect(screen.getByTestId('navbar-title')).toHaveTextContent('选择活动')
    })

    // 检查头部信息
    expect(screen.getByText('北京市 北京市 朝阳区 → 上海市 上海市 徐汇区')).toBeInTheDocument()
    expect(screen.getByTestId('header-date')).toHaveTextContent('2025-11-01')

    // 检查页面标题
    expect(screen.getByText('选择观看活动')).toBeInTheDocument()
    expect(screen.getByText('系统已根据您选择的地区自动匹配相关活动')).toBeInTheDocument()

    // 检查去程活动区域
    expect(screen.getByText('去程活动')).toBeInTheDocument()
    expect(screen.getByText('前往上海市 上海市 徐汇区观看活动')).toBeInTheDocument()

    // 检查活动名称是否正确分配到对应的区域
    expect(screen.getByTestId('departure-activity-name-1')).toHaveTextContent('音乐节活动')
    expect(screen.getByTestId('return-activity-name-2')).toHaveTextContent('体育赛事')

    // 检查返程活动区域
    expect(screen.getByText('返程活动')).toBeInTheDocument()
    expect(screen.getByText('从北京市 北京市 朝阳区观看活动后返回')).toBeInTheDocument()
  })

  test('应该正确显示活动列表', async () => {
    render(
      <Wrapper>
        <ActivitySelectPage />
      </Wrapper>
    )


    // 等待数据加载完成
    await waitFor(() => {
      expect(screen.getByText('音乐节活动')).toBeInTheDocument()
      expect(screen.getByText('体育赛事')).toBeInTheDocument()
    })

    // 检查活动信息完整显示
    expect(screen.getByText('朝阳区 · 北京市 · 北京市')).toBeInTheDocument()
    expect(screen.getByText('北京市朝阳区工人体育场北路')).toBeInTheDocument()
    expect(screen.getByText('到达：上海市 上海市 徐汇区')).toBeInTheDocument()

    // 检查活动图片占位符已被注释掉，不显示
    expect(screen.queryByText('活动图片')).not.toBeInTheDocument()
  })

  test('应该正确处理活动选择', async () => {
    render(
      <Wrapper>
        <ActivitySelectPage />
      </Wrapper>
    )

    // 等待数据加载完成
    await waitFor(() => {
      expect(screen.getByText('音乐节活动')).toBeInTheDocument()
    })

    // 点击去程活动
    const activityItem = screen.getByTestId('departure-activity-1')
    fireEvent.click(activityItem)

    // 检查导航被调用
    expect(taroMock.navigateTo).toHaveBeenCalledWith({
      url: expect.stringContaining('pages/schedule-list/ScheduleListPage')
    })

    // 检查导航参数正确
    const navigateCall = taroMock.navigateTo.mock.calls[0][0]
    expect(navigateCall.url).toContain('startAreaIds=[1,11,101]')
    expect(navigateCall.url).toContain('endAreaIds=[2,22,202]')
    expect(navigateCall.url).toContain('date=2025-11-01')
    expect(navigateCall.url).toContain('vehicleType=bus')
    expect(navigateCall.url).toContain('travelMode=carpool')
    expect(navigateCall.url).toContain('activityId=1')
    expect(navigateCall.url).toContain('routeType=departure')
  })

  test('应该处理返程活动选择', async () => {
    render(
      <Wrapper>
        <ActivitySelectPage />
      </Wrapper>
    )

    // 等待数据加载完成
    await waitFor(() => {
      expect(screen.getByText('体育赛事')).toBeInTheDocument()
    })

    // 点击返程活动
    const returnActivity = screen.getByTestId('return-activity-2')
    fireEvent.click(returnActivity)

    // 检查导航被调用
    expect(taroMock.navigateTo).toHaveBeenCalledWith({
      url: expect.stringContaining('pages/schedule-list/ScheduleListPage')
    })

    // 检查导航参数正确
    const navigateCall = taroMock.navigateTo.mock.calls[0][0]
    expect(navigateCall.url).toContain('routeType=return')
    expect(navigateCall.url).toContain('activityId=2')
  })

  test('应该处理无活动的情况', async () => {
    // 模拟无活动数据
    mockRouteClient.search.$get.mockResolvedValue({
      status: 200,
      json: async () => ({
        success: true,
        data: {
          routes: [],
          activities: []
        }
      })
    })

    render(
      <Wrapper>
        <ActivitySelectPage />
      </Wrapper>
    )

    // 检查无活动状态显示
    await waitFor(() => {
      expect(screen.getByText('暂无去程活动')).toBeInTheDocument()
      expect(screen.getByText('上海市 上海市 徐汇区当前没有相关活动')).toBeInTheDocument()

      expect(screen.getByText('暂无返程活动')).toBeInTheDocument()
      expect(screen.getByText('北京市 北京市 朝阳区当前没有相关活动')).toBeInTheDocument()
    })
  })

  test('应该处理加载状态', () => {
    // 模拟API延迟
    mockRouteClient.search.$get.mockImplementation(() => new Promise(() => {}))

    render(
      <Wrapper>
        <ActivitySelectPage />
      </Wrapper>
    )

    // 检查加载状态显示
    expect(screen.getByText('正在加载活动')).toBeInTheDocument()
    expect(screen.getByText('请稍候...')).toBeInTheDocument()
  })

  test('应该处理API错误', async () => {
    // 模拟API错误
    mockRouteClient.search.$get.mockRejectedValue(new Error('网络错误'))

    render(
      <Wrapper>
        <ActivitySelectPage />
      </Wrapper>
    )

    // 检查无活动状态显示（因为API错误导致无数据）
    await waitFor(() => {
      expect(screen.getByText('暂无去程活动')).toBeInTheDocument()
      expect(screen.getByText('暂无返程活动')).toBeInTheDocument()
    })
  })

  test('应该验证布局优化效果', async () => {
    render(
      <Wrapper>
        <ActivitySelectPage />
      </Wrapper>
    )

    // 等待数据加载完成
    await waitFor(() => {
      expect(screen.getByText('音乐节活动')).toBeInTheDocument()
    })

    // 验证图片占位符已被注释掉，不显示
    expect(screen.queryByText('活动图片')).not.toBeInTheDocument()

    // 验证活动信息完整显示
    expect(screen.getByText('音乐节活动')).toBeInTheDocument()
    expect(screen.getByText('朝阳区 · 北京市 · 北京市')).toBeInTheDocument()
    expect(screen.getByText('北京市朝阳区工人体育场北路')).toBeInTheDocument()
    expect(screen.getByText('到达：上海市 上海市 徐汇区')).toBeInTheDocument()

    // 验证头部日期显示正确
    expect(screen.getByTestId('header-date')).toHaveTextContent('2025-11-01')
  })

  test('应该处理返回按钮', async () => {
    render(
      <Wrapper>
        <ActivitySelectPage />
      </Wrapper>
    )

    // 等待数据加载完成
    await waitFor(() => {
      expect(screen.getByTestId('navbar')).toBeInTheDocument()
    })

    // 点击返回按钮
    const backButton = screen.getByTestId('navbar-back')
    fireEvent.click(backButton)

    // 检查返回导航被调用
    expect(mockNavigateBack).toHaveBeenCalled()
  })

  test('应该处理不同的路由参数', async () => {
    // 设置不同的路由参数
    mockUseRouter.mockReturnValue({
      params: {
        startAreaIds: '[3,33,303]',
        endAreaIds: '[4,44,404]',
        startAreaName: encodeURIComponent('广州市 广东省 天河区'),
        endAreaName: encodeURIComponent('深圳市 广东省 福田区'),
        date: '2025-11-02',
        vehicleType: 'business',
        travelMode: 'charter'
      }
    })

    render(
      <Wrapper>
        <ActivitySelectPage />
      </Wrapper>
    )

    // 检查头部信息显示正确的地区
    await waitFor(() => {
      expect(screen.getByText('广州市 广东省 天河区 → 深圳市 广东省 福田区')).toBeInTheDocument()
      expect(screen.getByTestId('header-date')).toHaveTextContent('2025-11-02')
    })
  })
})