/**
 * (detail query branches: idle/loading/error/success).
 */
import React from 'react'
import { render, screen } from '@testing-library/react'
import type {
  GetApiProductDetailResponse,
  GetApiProductResponse,
} from '@/services/api-product/apiProduct.schema'
import ApiProductDetailWrapper from '../index'

jest.mock('next-intl', () => ({
  useTranslations: () => (key: string, params?: Record<string, unknown>) =>
    params ? `${key}:${JSON.stringify(params)}` : key,
}))
jest.mock('@/services/api-product/apiProduct.query-options', () => ({
  useGetApiProductDetail: jest.fn(),
}))
jest.mock('@/share/components/full-page/404', () => ({
  __esModule: true,
  default: () => <div data-testid="detail-404">404</div>,
}))
jest.mock('@/share/components/full-page/loading', () => ({
  __esModule: true,
  default: () => <div data-testid="detail-loading">Loading</div>,
}))
jest.mock('@/share/layout/end-user/page', () => ({
  __esModule: true,
  default: ({
    title,
    children,
  }: {
    title: React.ReactNode
    children: React.ReactNode
  }) => (
    <div data-testid="eu-page-layout">
      <h1>{title}</h1>
      {children}
    </div>
  ),
}))
jest.mock('../about', () => ({
  __esModule: true,
  default: () => <div data-testid="about-section">AboutSection</div>,
}))
jest.mock('../list-application', () => ({
  __esModule: true,
  default: () => <div data-testid="list-app">ListApplication</div>,
}))
jest.mock('../steps', () => ({
  __esModule: true,
  default: () => <div data-testid="steps-section">StepsSection</div>,
}))

import { useGetApiProductDetail } from '@/services/api-product/apiProduct.query-options'

const useDetail = useGetApiProductDetail as jest.MockedFunction<
  typeof useGetApiProductDetail
>

type ApiProductDetailQueryResult = ReturnType<typeof useGetApiProductDetail>

const mockDetailQuery = (state: {
  data: GetApiProductDetailResponse | undefined
  isLoading: boolean
  isError: boolean
  isSuccess: boolean
}): ApiProductDetailQueryResult => state as unknown as ApiProductDetailQueryResult

const INLINE = { inlinetoasttype: '', inlinetoastmsgkey: '' } as const

const defaultApiProduct = (): GetApiProductResponse => ({
  id: 'api-detail',
  name: 'Payment API',
  displayName: 'Payment API',
  description: 'Desc',
  context: '/v1',
  version: 'v1',
  type: 'APIPRODUCT',
  createdTime: null,
  provider: 'P',
  lifeCycleStatus: 'PUBLISHED',
  thumbnailUri: '',
  avgRating: '0',
  throttlingPolicies: [],
  advertiseInfo: {
    advertised: false,
    apiExternalProductionEndpoint: null,
    apiExternalSandboxEndpoint: null,
    originalDevPortalUrl: null,
    apiOwner: null,
    vendor: 'V',
  },
  businessInformation: {
    businessOwner: null,
    businessOwnerEmail: null,
    technicalOwner: null,
    technicalOwnerEmail: null,
  },
  isSubscriptionAvailable: true,
  monetizationLabel: '',
  gatewayType: '',
  gatewayVendor: '',
  additionalProperties: [],
  monetizedInfo: false,
  egress: false,
  subtype: '',
  resourceCount: 0,
  aboutDescription: '',
  aboutImage: '',
  bannerDescription: 'Desc',
  bannerImage: '',
  operations: [],
  documentLink: undefined,
})

const mkApiProduct = (
  overrides: Partial<GetApiProductResponse> = {}
): GetApiProductResponse => ({
  ...defaultApiProduct(),
  ...overrides,
})

const mkDetailEnvelope = (
  product: GetApiProductResponse
): GetApiProductDetailResponse => ({
  message: 'ok',
  code: '200',
  data: product,
})

describe('[components/api-product/detail/index] ApiProductDetailWrapper', () => {
  beforeEach(() => {
    useDetail.mockReset()
  })

  describe('loading', () => {
    it('shows LoadingPage while query is loading', () => {
      useDetail.mockReturnValue(
        mockDetailQuery({
          data: undefined,
          isLoading: true,
          isError: false,
          isSuccess: false,
        })
      )
      render(<ApiProductDetailWrapper id="api-1" {...INLINE} />)
      expect(screen.getByTestId('detail-loading')).toBeInTheDocument()
      expect(useDetail).toHaveBeenCalledWith('api-1')
    })
  })

  describe('errors', () => {
    it('shows NotFound404 when query fails', () => {
      useDetail.mockReturnValue(
        mockDetailQuery({
          data: undefined,
          isLoading: false,
          isError: true,
          isSuccess: false,
        })
      )
      render(<ApiProductDetailWrapper id="api-1" {...INLINE} />)
      expect(screen.getByTestId('detail-404')).toBeInTheDocument()
    })
  })

  describe('idle (no loading, no success, no error)', () => {
    it('renders nothing visible', () => {
      useDetail.mockReturnValue(
        mockDetailQuery({
          data: undefined,
          isLoading: false,
          isError: false,
          isSuccess: false,
        })
      )
      const { container } = render(
        <ApiProductDetailWrapper id="api-3" {...INLINE} />
      )
      expect(container).toBeEmptyDOMElement()
    })
  })

  describe('success', () => {
    it('composes About, Listing, Steps with propagated inline toast props surface', () => {
      useDetail.mockReturnValue(
        mockDetailQuery({
          data: mkDetailEnvelope(mkApiProduct()),
          isLoading: false,
          isError: false,
          isSuccess: true,
        })
      )
      render(<ApiProductDetailWrapper id="api-1" {...INLINE} />)
      expect(screen.getByRole('heading', { name: 'Payment API' })).toBeInTheDocument()
      expect(screen.getByTestId('about-section')).toBeInTheDocument()
      expect(screen.getByTestId('list-app')).toBeInTheDocument()
      expect(screen.getByTestId('steps-section')).toBeInTheDocument()
    })

    it('renders banner title when bannerDescription is empty', () => {
      useDetail.mockReturnValue(
        mockDetailQuery({
          data: mkDetailEnvelope(
            mkApiProduct({
              name: 'Fallback API',
              bannerDescription: '',
            })
          ),
          isLoading: false,
          isError: false,
          isSuccess: true,
        })
      )
      render(<ApiProductDetailWrapper id="api-2" {...INLINE} />)
      expect(screen.getByRole('heading', { name: 'Fallback API' })).toBeInTheDocument()
    })
  })
})
