/**
 * (metadata, negative parse, happy FilterProvider contract, parse invocation).
 */
import React from 'react'
import { render, screen } from '@testing-library/react'
import { ITEMS_PER_PAGE } from '@/constants/api-product'

jest.mock('next-intl/server', () => ({
  getTranslations: (ns: string) =>
    Promise.resolve((key: string) => `${ns}.${key}`),
}))

jest.mock('@/providers/filter-provider', () => ({
  FilterProvider: ({
    filter,
    children,
  }: {
    filter: unknown
    children: React.ReactNode
  }) => (
    <div data-testid="filter-provider" data-filter={JSON.stringify(filter)}>
      {children}
    </div>
  ),
}))

jest.mock('@/util/filter', () => ({
  parseFilterSearchParams: jest.fn(),
}))

jest.mock('@/components/api-product', () => ({
  __esModule: true,
  default: () => <div data-testid="api-product-wrapper">ApiProductWrapper</div>,
}))

describe('[locale]/(end-user)/api-products/page.tsx', () => {
  const { parseFilterSearchParams } = jest.requireMock('@/util/filter') as {
    parseFilterSearchParams: jest.Mock
  }

  beforeEach(() => {
    parseFilterSearchParams.mockReset()
  })

  describe('generateMetadata', () => {
    it('uses layout namespace translation for title', async () => {
      const { generateMetadata } = await import('../page')
      const metadata = await generateMetadata()
      expect(metadata.title).toBe('layout.header.apiproducts')
      expect(metadata.description).toBe('')
    })
  })

  describe('negative — invalid query parsing', () => {
    it.each([
      {
        outcome: 'string error marker',
        result: { error: 'invalid' as const, data: null },
      },
      {
        outcome: 'Error instance',
        result: { error: new Error('bad'), data: null },
      },
    ])('renders invalid params message ($outcome)', async ({ result }) => {
      parseFilterSearchParams.mockReturnValue(result)
      const { default: ApiProductsPage } = await import('../page')

      const element = await ApiProductsPage({
        searchParams: Promise.resolve({}),
      } as never)

      render(element as React.ReactElement)

      expect(screen.getByText('Invalid Query Params')).toBeInTheDocument()
      expect(screen.queryByTestId('filter-provider')).not.toBeInTheDocument()
    })
  })

  describe('happy path', () => {
    it('merges ITEMS_PER_PAGE limit and passes merged searchParams to parser', async () => {
      parseFilterSearchParams.mockReturnValue({
        error: null,
        data: { page: 1, limit: 10 },
      })
      const { default: ApiProductsPage } = await import('../page')

      await ApiProductsPage({
        searchParams: Promise.resolve({ page: 2, keyword: 'loan' }),
      } as never)

      expect(parseFilterSearchParams).toHaveBeenCalledWith({
        page: 2,
        keyword: 'loan',
        limit: ITEMS_PER_PAGE,
      })
    })

    it('wraps ApiProductWrapper in FilterProvider using parsed filter', async () => {
      parseFilterSearchParams.mockReturnValue({
        error: null,
        data: { page: 1, limit: 10 },
      })
      const { default: ApiProductsPage } = await import('../page')

      const element = await ApiProductsPage({
        searchParams: Promise.resolve({ page: 2 }),
      } as never)

      render(element as React.ReactElement)

      const provider = screen.getByTestId('filter-provider')
      expect(provider).toHaveAttribute(
        'data-filter',
        JSON.stringify({ page: 1, limit: 10 })
      )
      expect(screen.getByTestId('api-product-wrapper')).toBeInTheDocument()
    })
  })
})
