import { NextRequest, NextResponse } from 'next/server';
import { LOCALES, DEFAULT_LOCALE, LOCALE_COOKIE, LOCALE_HEADER, COUNTRY_HEADER, isLocale, Locale } from '@/lib/locales';

/**
 * Locale-detection middleware (Session 12).
 *
 * Detection priority:
 *   1. URL prefix (/es/scan, /fr/pricing) — reserved for a future
 *      session that does the [locale] segment refactor. For now this
 *      branch is unreachable because no route uses the prefix.
 *   2. NEXT_LOCALE cookie — set by the locale switcher and persisted
 *      across sessions.
 *   3. Accept-Language header — best guess from the browser.
 *   4. Default 'en'.
 *
 * The resolved locale lands on the `x-vyndr-locale` REQUEST header
 * (NOT the response) so downstream server components can read it via
 * `headers()` without parsing cookies themselves. The cookie is set
 * on the response when the locale switcher fires (separate code
 * path); the middleware itself doesn't write cookies.
 *
 * Skips: Next.js internals (`_next`), public files (anything with a
 * dot in the path), and API routes (they don't render UI, no locale
 * needed).
 */

function parseAcceptLanguage(header: string | null): Locale | null {
  if (!header) return null;
  // "en-US,en;q=0.9,es;q=0.8" → [{lang:'en-us', q:1}, {lang:'en', q:0.9}, ...]
  const ranked = header
    .split(',')
    .map((chunk) => {
      const [tag, ...params] = chunk.trim().split(';');
      const qParam = params.find((p) => p.trim().startsWith('q='));
      const q = qParam ? Number(qParam.split('=')[1]) : 1;
      return { tag: tag.toLowerCase(), q: Number.isFinite(q) ? q : 1 };
    })
    .filter((entry) => entry.tag)
    .sort((a, b) => b.q - a.q);

  for (const entry of ranked) {
    // Match the primary subtag (en-US → en).
    const primary = entry.tag.split('-')[0];
    if (isLocale(primary)) return primary;
  }
  return null;
}

function resolveLocale(req: NextRequest): Locale {
  // 1. URL prefix — placeholder for the future [locale] refactor.
  //    Check the first path segment against the locale registry.
  const firstSegment = req.nextUrl.pathname.split('/')[1] || '';
  if (isLocale(firstSegment)) return firstSegment;

  // 2. Cookie.
  const cookie = req.cookies.get(LOCALE_COOKIE)?.value;
  if (isLocale(cookie)) return cookie;

  // 3. Accept-Language.
  const fromHeader = parseAcceptLanguage(req.headers.get('accept-language'));
  if (fromHeader) return fromHeader;

  // 4. Default.
  return DEFAULT_LOCALE;
}

export function middleware(req: NextRequest) {
  const locale = resolveLocale(req);
  // Session 13 — Cloudflare stamps `cf-ipcountry` on every edge
  // request. We copy it onto `x-vyndr-country` so server components
  // don't have to know about Cloudflare directly. Empty string when
  // requests bypass Cloudflare (local dev, direct origin hits) —
  // consumers MUST treat empty as "unknown" and degrade
  // conservatively (the Africa-tier gate hides the card).
  const country = (req.headers.get('cf-ipcountry') || '').toUpperCase();

  const requestHeaders = new Headers(req.headers);
  requestHeaders.set(LOCALE_HEADER, locale);
  requestHeaders.set(COUNTRY_HEADER, country);
  return NextResponse.next({
    request: { headers: requestHeaders },
  });
}

// Skip Next.js internals, public files, and API routes (no UI).
export const config = {
  matcher: ['/((?!api|_next|.*\\..*).*)'],
};

// Re-export so tests can import without pulling the full middleware.
export { resolveLocale, parseAcceptLanguage };
export const __SUPPORTED_LOCALES = LOCALES;
