// @vitest-environment jsdom
//
// Root layout — renders the top nav whose Home link + language switcher are
// locale-prefixed off the CURRENT url (useUrlLocale → useLocation). We mock
// useLocation (@voltro/web) to drive the active locale, and mock @voltro/i18n so
// <I18nProvider> is a pass-through and <T> resolves against the real catalogs.

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 en from '../locales/en'
import de from '../locales/de'

const location = vi.fn<() => string>()
vi.mock('@voltro/web', () => ({ useLocation: () => location() }))

const catalogs: Record<string, Record<string, string>> = { en, de }
const localeFor = (path: string): string => (/^\/de(?:\/|$)/.test(path) ? 'de' : 'en')

vi.mock('@voltro/i18n', () => ({
  // The locale catalogs call these at module top-level; identity mirrors the
  // real (compile-time-only) implementations so importing them doesn't throw.
  defineCatalog: <T,>(c: T): T => c,
  defineLocale:
    () =>
    <T,>(c: T): T =>
      c,
  I18nProvider: ({ children }: { children?: ReactNode }) => children,
  // The nav uses <T> for link labels; resolve against the catalog of the
  // locale implied by the current path (matches what useUrlLocale computes).
  T: ({ id }: { id: string }) => catalogs[localeFor(location())]?.[id] ?? id,
}))

const { default: Layout } = await import('./layout')

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

let container: HTMLDivElement
let root: Root

const render = (node: ReactNode): void => {
  container = document.createElement('div')
  document.body.appendChild(container)
  act(() => {
    root = createRoot(container)
    root.render(node)
  })
}

const hrefs = (): Array<string | null> =>
  Array.from(container.querySelectorAll('a')).map((a) => a.getAttribute('href'))

beforeEach(() => location.mockReset())

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

describe('docs layout — English (bare path)', () => {
  test('renders a bare Home link, an English nav label and the DE switcher target', () => {
    location.mockReturnValue('/docs/intro/getting-started')
    render(createElement(Layout, { children: createElement('p', null, 'page') }))
    const h = hrefs()
    expect(h).toContain('/')
    // the language switcher keeps you on the same doc, re-prefixed per locale
    expect(h).toContain('/de/docs/intro/getting-started')
    expect(container.textContent).toContain('Home')
    expect(container.textContent).toContain('page')
  })
})

describe('docs layout — German (/de prefix)', () => {
  test('prefixes the home link with /de and renders German labels', () => {
    location.mockReturnValue('/de/docs/intro/getting-started')
    render(createElement(Layout, { children: null }))
    const h = hrefs()
    expect(h).toContain('/de')
    // switching back to en strips the prefix
    expect(h).toContain('/docs/intro/getting-started')
    expect(container.textContent).toContain('Start')
  })
})
