/**
 * (auth gate, parse error, happy FilterProvider, login mutation).
 */
import React from 'react'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import ListApplication from '../index'

jest.mock('next-intl', () => ({
  useTranslations: () => (k: string) => k,
  useLocale: () => 'vi',
}))
let mockSearchParams = new URLSearchParams()
jest.mock('next/navigation', () => ({
  useSearchParams: () => mockSearchParams,
}))
jest.mock('@/providers/auth-session-provider', () => ({
  useAuthSession: jest.fn(),
}))
const mockMutate = jest.fn()
jest.mock('@/share/layout/end-user/header/hook', () => ({
  useGetUrlLoginMutation: () => ({ mutate: mockMutate }),
}))
jest.mock('@/share/components/empty-state', () => ({
  __esModule: true,
  default: ({
    title,
    buttonTitle,
    onClick,
  }: {
    title: string
    buttonTitle: string
    onClick: () => void
  }) => (
    <div data-testid="empty-state">
      <span>{title}</span>
      <button type="button" onClick={onClick}>{buttonTitle}</button>
    </div>
  ),
}))
jest.mock('@/providers/filter-provider', () => ({
  FilterProvider: ({ children }: { children: React.ReactNode }) => (
    <div data-testid="filter-provider">{children}</div>
  ),
}))
jest.mock('@/util/filter', () => ({ parseFilterSearchParams: jest.fn() }))
jest.mock('@/components/application/listing', () => ({
  __esModule: true,
  default: () => <div data-testid="listing-view">ListingView</div>,
}))

import { useAuthSession } from '@/providers/auth-session-provider'

const useAuthSessionMock = useAuthSession as jest.MockedFunction<
  typeof useAuthSession
>
const { parseFilterSearchParams } = jest.requireMock('@/util/filter') as {
  parseFilterSearchParams: jest.Mock
}

const defaultProps = {
  api_id: 'api-1',
  api_product_name: 'test-api-product',
  inlinetoasttype: 'create-success',
  inlinetoastmsgkey: '',
} as const

describe('[components/api-product/detail/list-application] ListApplication', () => {
  beforeEach(() => {
    mockSearchParams = new URLSearchParams()
    mockMutate.mockClear()
    useAuthSessionMock.mockReturnValue({ authSession: null } as never)
    parseFilterSearchParams.mockReturnValue({
      data: { limit: 10, offset: 0 },
      error: null,
    })
  })

  describe('guest — no authSession', () => {
    it('renders EmptyState with listing copy and login CTA', () => {
      render(<ListApplication {...defaultProps} />)
      expect(screen.getByText('listing.not_auth.title')).toBeInTheDocument()
      expect(screen.getByText('btn.login')).toBeInTheDocument()
    })

    it('login CTA invokes URL login mutation', async () => {
      render(<ListApplication {...defaultProps} />)
      await userEvent.click(screen.getByText('btn.login'))
      expect(mockMutate).toHaveBeenCalledTimes(1)
    })
  })

  describe('authenticated', () => {
    beforeEach(() => {
      useAuthSessionMock.mockReturnValue({ authSession: {} } as never)
    })

    it('renders ListingView when parse succeeds', () => {
      render(<ListApplication {...defaultProps} />)
      expect(screen.getByTestId('listing-view')).toBeInTheDocument()
      expect(screen.getByTestId('filter-provider')).toBeInTheDocument()
    })

    it('shows invalid query message when parse fails', () => {
      parseFilterSearchParams.mockReturnValue({
        data: null,
        error: new Error('invalid'),
      })
      render(<ListApplication {...defaultProps} />)
      expect(screen.getByText('Invalid Query Params')).toBeInTheDocument()
      expect(screen.queryByTestId('listing-view')).not.toBeInTheDocument()
    })

    it('passes numeric page and limit from URL into parseFilterSearchParams', () => {
      mockSearchParams = new URLSearchParams('page=2&limit=20')
      render(<ListApplication {...defaultProps} />)
      expect(parseFilterSearchParams).toHaveBeenCalledWith({
        page: 2,
        limit: 20,
      })
    })
  })
})
