/**
 * SettingsPage 页面测试
 * 使用真实的React Query和RPC类型验证
 */
import React from 'react'
import { render, screen, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import Taro from '@tarojs/taro'
import { useRequireAuth } from '@d8d/rencai-auth-ui/hooks'

// Mock auth hooks
jest.mock('@d8d/rencai-auth-ui/hooks', () => ({
  useRequireAuth: jest.fn()
}))

// Mock API client - 使用真实的RPC类型
jest.mock('@d8d/rencai-settings-ui/api', () => ({
  talentSettingsClient: {
    me: {
      $get: jest.fn()
    },
    logout: {
      $post: jest.fn()
    }
  }
}))

// Mock shared components
jest.mock('@d8d/mini-shared-ui-components/components/navbar', () => ({
  Navbar: ({ title, children }: any) => <div data-testid="navbar">{title}{children}</div>
}))

jest.mock('@d8d/rencai-shared-ui/components/RencaiTabBarLayout', () => ({
  RencaiTabBarLayout: ({ children, activeKey }: any) => (
    <div data-testid="tabbar" data-active={activeKey}>{children}</div>
  )
}))

import { talentSettingsClient } from '../../../src/api'
import SettingsPage from '../../../src/pages/SettingsPage/SettingsPage'

const createMockResponse = <T,>(status: number, data: T) => ({
  status,
  ok: status >= 200 && status < 300,
  json: async () => data
})

const createTestWrapper = () => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
        staleTime: Infinity,
        refetchOnWindowFocus: false
      },
      mutations: {
        retry: false
      }
    }
  })

  return ({ children }: { children: React.ReactNode }) => (
    <QueryClientProvider client={queryClient}>
      {children}
    </QueryClientProvider>
  )
}

describe('SettingsPage', () => {
  beforeEach(() => {
    jest.clearAllMocks()
    // Mock useRequireAuth to do nothing (user is authenticated)
    ;(useRequireAuth as jest.Mock).mockImplementation(() => {})
    // Reset Taro API mocks
    ;(Taro.showModal as jest.Mock).mockClear()
    ;(Taro.showToast as jest.Mock).mockClear()
    ;(Taro.navigateTo as jest.Mock).mockClear()
    ;(Taro.reLaunch as jest.Mock).mockClear()
    ;(Taro.removeStorageSync as jest.Mock).mockClear()
  })

  it('应该渲染页面标题', async () => {
    ;(talentSettingsClient.me.$get as jest.Mock).mockResolvedValue(
      createMockResponse(200, { id: 1, name: '张明' })
    )

    const wrapper = createTestWrapper()
    render(<SettingsPage />, { wrapper })

    await waitFor(() => {
      expect(screen.getByText('更多')).toBeInTheDocument()
    })
  })

  it('应该渲染个人信息摘要', async () => {
    ;(talentSettingsClient.me.$get as jest.Mock).mockResolvedValue(
      createMockResponse(200, {
        id: 1,
        name: '张明',
        personInfo: {
          disabilityType: '肢体残疾',
          disabilityLevel: '三级'
        }
      })
    )

    const wrapper = createTestWrapper()
    render(<SettingsPage />, { wrapper })

    await waitFor(() => {
      expect(screen.getByText('张明')).toBeInTheDocument()
    })
  })

  it('应该渲染功能入口列表', async () => {
    ;(talentSettingsClient.me.$get as jest.Mock).mockResolvedValue(
      createMockResponse(200, { id: 1, name: '张明' })
    )

    const wrapper = createTestWrapper()
    render(<SettingsPage />, { wrapper })

    await waitFor(() => {
      expect(screen.getByText('修改个人信息')).toBeInTheDocument()
      expect(screen.getByText('账号与安全')).toBeInTheDocument()
      expect(screen.getByText('消息通知设置')).toBeInTheDocument()
    })
  })

  it('应该渲染帮助与支持入口', async () => {
    ;(talentSettingsClient.me.$get as jest.Mock).mockResolvedValue(
      createMockResponse(200, { id: 1, name: '张明' })
    )

    const wrapper = createTestWrapper()
    render(<SettingsPage />, { wrapper })

    await waitFor(() => {
      expect(screen.getByText('帮助中心')).toBeInTheDocument()
      expect(screen.getByText('用户协议')).toBeInTheDocument()
      expect(screen.getByText('隐私政策')).toBeInTheDocument()
    })
  })

  it('应该渲染退出登录按钮', async () => {
    ;(talentSettingsClient.me.$get as jest.Mock).mockResolvedValue(
      createMockResponse(200, { id: 1, name: '张明' })
    )

    const wrapper = createTestWrapper()
    render(<SettingsPage />, { wrapper })

    await waitFor(() => {
      expect(screen.getByText('退出登录')).toBeInTheDocument()
    })
  })

  it('API失败时应该显示错误信息', async () => {
    ;(talentSettingsClient.me.$get as jest.Mock).mockResolvedValue(
      createMockResponse(404, {})
    )

    const wrapper = createTestWrapper()
    render(<SettingsPage />, { wrapper })

    await waitFor(() => {
      expect(screen.getByText('加载失败，请稍后重试')).toBeInTheDocument()
    })
  })

  it('API返回空数据时应该使用模拟数据', async () => {
    ;(talentSettingsClient.me.$get as jest.Mock).mockResolvedValue(
      createMockResponse(200, null)
    )

    const wrapper = createTestWrapper()
    render(<SettingsPage />, { wrapper })

    await waitFor(() => {
      expect(screen.getByText('张明')).toBeInTheDocument()
    })
  })

  it('应该渲染加载状态', () => {
    ;(talentSettingsClient.me.$get as jest.Mock).mockImplementation(
      () => new Promise(() => {}) // 永不resolve
    )

    const wrapper = createTestWrapper()
    render(<SettingsPage />, { wrapper })

    expect(screen.getByText('加载中...')).toBeInTheDocument()
  })
})
