import { beforeEach, describe, expect, it, vi } from 'vitest'

const nextServer = vi.hoisted(() => {
  const next = vi.fn((init?: { request?: { headers?: Headers } }) => ({
    kind: 'next',
    init,
    cookies: { set: vi.fn() },
  }))
  const MockNextResponse = vi.fn((body?: string, init?: { status?: number }) => ({
    kind: 'response', body, status: init?.status,
  })) as any
  MockNextResponse.next = next
  return { next, MockNextResponse }
})

vi.mock('next/server', () => ({ NextResponse: nextServer.MockNextResponse }))

function request(options: { cookies?: Record<string, string>; headers?: Record<string, string> } = {}) {
  const cookies = new Map(Object.entries(options.cookies ?? {}))
  return {
    cookies: { get: vi.fn((name: string) => cookies.has(name) ? { value: cookies.get(name) } : undefined) },
    headers: new Headers(options.headers ?? {}),
  }
}

beforeEach(() => nextServer.next.mockClear())

describe('Carplace language bootstrap', () => {
  it('rejects forged middleware subrequest headers', async () => {
    const { proxy } = await import('./proxy')
    const response = proxy(request({ headers: { 'x-middleware-subrequest': 'middleware:middleware' } }) as never) as any
    expect(response).toEqual({ kind: 'response', body: 'Unsupported internal request header', status: 400 })
    expect(nextServer.next).not.toHaveBeenCalled()
  })

  it('keeps a valid shared language cookie unchanged', async () => {
    const { proxy } = await import('./proxy')
    const response = proxy(request({ cookies: { 'rentaldrivego-language': 'fr' } }) as never) as any
    expect(response.kind).toBe('next')
    expect(response.cookies.set).not.toHaveBeenCalled()
  })

  it.each([
    ['ar-MA,fr;q=0.8', 'ar'],
    ['de-DE,fr-FR;q=0.7', 'fr'],
    ['de-DE,es;q=0.9', 'en'],
  ])('resolves %s as %s', async (acceptLanguage, expected) => {
    const { proxy } = await import('./proxy')
    const response = proxy(request({ headers: { 'accept-language': acceptLanguage } }) as never) as any
    expect(response.cookies.set).toHaveBeenCalledWith('rentaldrivego-language', expected, expect.objectContaining({ path: '/', sameSite: 'lax' }))
    expect(response.init?.request?.headers?.get('cookie')).toBe(`rentaldrivego-language=${expected}`)
  })
})
