/**
 * (verify-token query: loading, error→notFound, idle, success branches by status).
 */
import React from 'react'
import { render, screen } from '@testing-library/react'

import CallbackWrapper from '../index'

const mockUseVerifyToken = jest.fn()

jest.mock('@/share/components/full-page/loading', () => ({
  __esModule: true,
  default: () => <div data-testid="callback-loading">Loading</div>,
}))
jest.mock('@/services/auth/auth.query-options', () => ({
  useVerifyToken: (token: string) => mockUseVerifyToken(token),
}))
jest.mock('next/navigation', () => ({
  notFound: jest.fn(() => <div data-testid="callback-not-found">not-found</div>),
}))
jest.mock('../expired', () => ({
  __esModule: true,
  default: () => <div data-testid="expired-ui">ExpiredUI</div>,
}))
jest.mock('../verified', () => ({
  __esModule: true,
  default: () => <div data-testid="verified-ui">VerifiedUI</div>,
}))

describe('[components/auth/call-back] CallbackWrapper', () => {
  beforeEach(() => {
    mockUseVerifyToken.mockReset()
    const { notFound } = require('next/navigation')
    notFound.mockClear()
  })

  describe('loading', () => {
    it('renders loading page while verify query runs', () => {
      mockUseVerifyToken.mockReturnValue({
        data: undefined,
        isLoading: true,
        error: null,
        isSuccess: false,
      })

      render(<CallbackWrapper token="t" />)
      expect(screen.getByTestId('callback-loading')).toBeInTheDocument()
    })
  })

  describe('error', () => {
    it('invokes notFound when verify fails', () => {
      const { notFound } = require('next/navigation')
      mockUseVerifyToken.mockReturnValue({
        data: undefined,
        isLoading: false,
        error: new Error('bad'),
        isSuccess: false,
      })

      render(<CallbackWrapper token="t" />)
      expect(notFound).toHaveBeenCalledTimes(1)
      expect(screen.getByTestId('callback-not-found')).toBeInTheDocument()
    })
  })

  describe('idle — no data yet', () => {
    it('renders nothing when not loading, no error, not success', () => {
      mockUseVerifyToken.mockReturnValue({
        data: undefined,
        isLoading: false,
        error: null,
        isSuccess: false,
      })

      render(<CallbackWrapper token="t" />)
      expect(screen.queryByTestId('expired-ui')).not.toBeInTheDocument()
      expect(screen.queryByTestId('verified-ui')).not.toBeInTheDocument()
      expect(screen.queryByTestId('callback-loading')).not.toBeInTheDocument()
    })
  })

  describe('success — status routing', () => {
    it('renders ExpiredStatus when status is EXPIRED', () => {
      mockUseVerifyToken.mockReturnValue({
        data: { data: { status: 'EXPIRED' } },
        isLoading: false,
        error: null,
        isSuccess: true,
      })

      render(<CallbackWrapper token="t" />)
      expect(screen.getByTestId('expired-ui')).toBeInTheDocument()
    })

    it('renders VerifiedStatus when status is ACTIVE', () => {
      mockUseVerifyToken.mockReturnValue({
        data: { data: { status: 'ACTIVE' } },
        isLoading: false,
        error: null,
        isSuccess: true,
      })

      render(<CallbackWrapper token="t" />)
      expect(screen.getByTestId('verified-ui')).toBeInTheDocument()
    })

    it('calls notFound for unsupported status values', () => {
      const { notFound } = require('next/navigation')
      mockUseVerifyToken.mockReturnValue({
        data: { data: { status: 'PENDING' } },
        isLoading: false,
        error: null,
        isSuccess: true,
      })

      render(<CallbackWrapper token="t" />)
      expect(notFound).toHaveBeenCalledTimes(1)
      expect(screen.getByTestId('callback-not-found')).toBeInTheDocument()
    })
  })

  describe('contract — hook args', () => {
    it('passes token prop to useVerifyToken', () => {
      mockUseVerifyToken.mockReturnValue({
        data: undefined,
        isLoading: true,
        error: null,
        isSuccess: false,
      })

      render(<CallbackWrapper token="my-token" />)
      expect(mockUseVerifyToken).toHaveBeenCalledWith('my-token')
      expect(mockUseVerifyToken).toHaveBeenCalledTimes(1)
    })
  })
})
