// @vitest-environment jsdom
//
// `/` SSR page — its `meta`, its per-request `loader`, and the render reading
// both the loader data and the incoming request (via useServerRequest). The
// hooks are backed by a <Router> context in the real app, so we mock
// `@voltro/web` and drive the data directly.

import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
import { act, createElement, type ReactNode } from 'react'
import { createRoot, type Root } from 'react-dom/client'
import { I18nProvider } from '@voltro/i18n'
import enCatalog from '../locales/en'

const loaderData = vi.fn<() => unknown>()
const serverRequest = vi.fn<() => unknown>()
vi.mock('@voltro/web', () => ({
  useLoaderData: () => loaderData(),
  useServerRequest: () => serverRequest(),
}))

const { default: Home, meta, loader, renderMode } = await import('./page')

;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true

let container: HTMLDivElement
let root: Root

// The page uses <T>, so it needs an <I18nProvider>. Wrap with the real English
// catalog (the framework auto-wires this provider in the running app).
const render = (node: ReactNode): void => {
  container = document.createElement('div')
  document.body.appendChild(container)
  act(() => {
    root = createRoot(container)
    root.render(
      createElement(I18nProvider, { locale: 'en', messages: enCatalog, defaultLocale: 'en', children: node }),
    )
  })
}

beforeEach(() => {
  loaderData.mockReset()
  serverRequest.mockReset()
})

afterEach(() => {
  if (root) act(() => root.unmount())
  container?.remove()
  document.body.innerHTML = ''
})

describe('index — config + meta', () => {
  test('renders per request (ssr) and declares a title', () => {
    expect(renderMode).toBe('ssr')
    const m = meta({ locale: 'en' })
    expect(m.title).toContain('SSR')
    expect(m.description).toContain('every request')
  })
})

describe('index — loader', () => {
  test('resolves a fresh ISO timestamp + a numeric nonce', async () => {
    const data = await loader({} as never)
    expect(Number.isNaN(Date.parse(data.renderedAt))).toBe(false)
    expect(typeof data.nonce).toBe('number')
  })
})

describe('index — render', () => {
  test('shows the loader data + falls back to `unset` when the request is empty', () => {
    loaderData.mockReturnValue({ renderedAt: '2020-01-01T00:00:00.000Z', nonce: 42 })
    serverRequest.mockReturnValue(undefined)
    render(createElement(Home))
    expect(container.textContent).toContain('2020-01-01T00:00:00.000Z')
    expect(container.textContent).toContain('42')
    expect(container.textContent).toContain('unset')
  })

  test('surfaces the accept-language header + theme cookie from the request', () => {
    loaderData.mockReturnValue({ renderedAt: '2020-01-01T00:00:00.000Z', nonce: 1 })
    serverRequest.mockReturnValue({
      headers: { 'accept-language': 'de-DE' },
      cookies: { 'voltro:theme': 'dark' },
    })
    render(createElement(Home))
    expect(container.textContent).toContain('de-DE')
    expect(container.textContent).toContain('dark')
  })
})
