/**
 * Locale detection middleware.
 *
 * Determines the current locale using the following precedence:
 * 1. `?lang=he|en` query param (sets cookie for stickiness)
 * 2. Cookie `multideal_locale` (explicit user preference)
 * 3. Default: `he` (Hebrew)
 *
 * Accept-Language is intentionally NOT consulted: Hebrew is the product default
 * for new visitors. Browsers with English-only Accept-Language headers would
 * otherwise serve EN on first visit, causing a flash when client preferences
 * later flip to HE.
 *
 * Sets `locals.locale` to the resolved locale string.
 */

import { defineMiddleware } from 'astro:middleware';
import { runWithRequestLocale } from '@/server/i18n/request-locale';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export type MultidealLocale = 'he' | 'en';

const SUPPORTED_LOCALES: readonly MultidealLocale[] = ['he', 'en'] as const;
const DEFAULT_LOCALE: MultidealLocale = 'he';
const LOCALE_COOKIE_NAME = 'multideal_locale';

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function parseCookie(cookieHeader: string | null, name: string): string | undefined {
  if (!cookieHeader) return undefined;
  const cookies = cookieHeader.split(';').map((p) => p.trim());
  for (const cookie of cookies) {
    const eqIdx = cookie.indexOf('=');
    if (eqIdx === -1) continue;
    const key = cookie.slice(0, eqIdx).trim();
    if (key === name) return cookie.slice(eqIdx + 1).trim();
  }
  return undefined;
}

function normalizeLocale(raw: string | undefined): MultidealLocale {
  if (!raw) return DEFAULT_LOCALE;
  const lower = raw.toLowerCase().split('-')[0] ?? '';
  return (
    (SUPPORTED_LOCALES.find((l) => l === lower) as MultidealLocale | undefined) ?? DEFAULT_LOCALE
  );
}

// ---------------------------------------------------------------------------
// Middleware
// ---------------------------------------------------------------------------

export const localeMiddleware = defineMiddleware(async (context, next) => {
  const cookieHeader = context.request.headers.get('cookie');
  const cookieLocale = parseCookie(cookieHeader, LOCALE_COOKIE_NAME);

  const queryLangRaw = new URL(context.request.url).searchParams.get('lang');
  const queryLocale = queryLangRaw
    ? SUPPORTED_LOCALES.find((l) => l === queryLangRaw.toLowerCase())
    : undefined;

  let locale: MultidealLocale;

  if (queryLocale) {
    locale = queryLocale;
  } else if (cookieLocale) {
    locale = normalizeLocale(cookieLocale);
  } else {
    locale = DEFAULT_LOCALE;
  }

  context.locals.locale = locale;

  const response = await runWithRequestLocale(locale, () => next());

  // Skip header mutation for WS upgrade (101) — response.headers are immutable.
  if (response.status === 101) return response;

  if (queryLocale) {
    response.headers.append(
      'Set-Cookie',
      `${LOCALE_COOKIE_NAME}=${queryLocale}; Path=/; Max-Age=31536000; SameSite=Lax`,
    );
  }

  return response;
});
