import { NextRequest, NextResponse } from "next/server";
import { match as matchLocale } from "@formatjs/intl-localematcher";
import Negotiator from "negotiator";
const PUBLIC_PAGES = ["/login", "/register"];

const LOCALES = ["uz", "ru", "en"];
const DEFAULT_LOCALE = "uz";

type Locale = (typeof LOCALES)[number];

function getLocaleFromPathname(pathname: string): Locale | null {
  const segments = pathname.split("/").filter(Boolean);
  const firstSegment = segments[0];

  if (firstSegment && LOCALES.includes(firstSegment as Locale)) {
    return firstSegment as Locale;
  }

  return null;
}

function getLocaleFromCookie(request: NextRequest): Locale | null {
  const cookieLocale = request.cookies.get("NEXT_LOCALE")?.value;

  if (cookieLocale && LOCALES.includes(cookieLocale as Locale)) {
    return cookieLocale as Locale;
  }

  return null;
}

function getLocaleFromHeaders(request: NextRequest): Locale {
  const negotiatorHeaders: Record<string, string> = {};
  request.headers.forEach((value, key) => {
    negotiatorHeaders[key] = value;
  });

  const languages = new Negotiator({ headers: negotiatorHeaders }).languages();

  try {
    return matchLocale(
      languages,
      LOCALES as unknown as string[],
      DEFAULT_LOCALE
    ) as Locale;
  } catch {
    return DEFAULT_LOCALE;
  }
}

export function middleware(request: NextRequest) {
  const { pathname, search } = request.nextUrl;

  // Skip public files and API routes
  if (
    pathname.includes(".") ||
    pathname.startsWith("/api") ||
    pathname.startsWith("/_next")
  ) {
    return NextResponse.next();
  }

  // 1. Check URL locale
  const localeFromPath = getLocaleFromPathname(pathname);

  // 2. Check cookie locale
  const localeFromCookie = getLocaleFromCookie(request);

  // 3. Check browser locale
  const localeFromBrowser = getLocaleFromHeaders(request);

  // Priority: URL > Cookie > Browser
  const preferredLocale =
    localeFromPath || localeFromCookie || localeFromBrowser;

  // Faqat kerakli sahifalarni redirect qilamiz
  const isPublicPage = PUBLIC_PAGES.some((page) => pathname === page);

  if (isPublicPage) {
    const url = request.nextUrl.clone();
    url.pathname = `/${DEFAULT_LOCALE}/verify-otp`;
    url.search = search; // ?code=1111&phone=...

    return NextResponse.redirect(url);
  }

  // If URL has no locale, redirect with preferred locale
  if (!localeFromPath) {
    const newUrl = new URL(`/${preferredLocale}/${pathname}`, request.url);
    return NextResponse.redirect(newUrl);
  }

  // If URL locale differs from cookie, update cookie
  if (localeFromPath !== localeFromCookie) {
    const response = NextResponse.next();

    // ✅ Set cookie on server side
    response.cookies.set("NEXT_LOCALE", localeFromPath, {
      path: "/",
      maxAge: 31536000, // 1 year
      sameSite: "lax",
    });

    // ✅ Pass locale to request headers for server components
    const requestHeaders = new Headers(request.headers);
    requestHeaders.set("x-locale", localeFromPath);
    requestHeaders.set("x-pathname", pathname);

    return NextResponse.next({
      request: {
        headers: requestHeaders,
      },
    });
  }

  // Normal flow - just pass locale in headers
  const response = NextResponse.next();
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set("x-locale", localeFromPath);
  requestHeaders.set("x-pathname", pathname);

  return NextResponse.next({
    request: {
      headers: requestHeaders,
    },
  });
}

export const config = {
  matcher: [
    // Match all pathnames except for
    // - … if they start with `/api`, `/_next` or `/_vercel`
    // - … the ones containing a dot (e.g. `favicon.ico`)
    '/((?!api|_next|_vercel|.*\\..*).*)',
  ],
};