"use client";

import { createContext, useContext, useEffect, useState } from "react";
import { NextIntlClientProvider } from "next-intl";

export const SUPPORTED_LOCALES = [
  { code: "en", label: "English" },
  { code: "fr", label: "Français" },
] as const;

export type Locale = (typeof SUPPORTED_LOCALES)[number]["code"];

const STORAGE_KEY = "epicure-locale";

const LocaleContext = createContext<{
  locale: Locale;
  setLocale: (locale: Locale) => Promise<boolean>;
}>({ locale: "en", setLocale: async () => false });

export function useLocale() {
  return useContext(LocaleContext);
}

export function I18nProvider({
  children,
  messages,
  initialLocale,
}: {
  children: React.ReactNode;
  messages: Record<string, Record<string, unknown>>;
  initialLocale?: Locale;
}) {
  const resolved = initialLocale ?? ("en" as Locale);
  const [locale, setLocaleState] = useState<Locale>(resolved);
  const [currentMessages, setCurrentMessages] = useState(messages[resolved] ?? messages["en"]!);

  useEffect(() => {
    // If no server-side locale, fall back to localStorage
    if (!initialLocale) {
      const stored = localStorage.getItem(STORAGE_KEY) as Locale | null;
      if (stored && messages[stored]) {
        setLocaleState(stored);
        setCurrentMessages(messages[stored]!);
      }
    }
  }, [messages, initialLocale]);

  async function setLocale(next: Locale): Promise<boolean> {
    const previous = locale;
    const previousMessages = currentMessages;
    setLocaleState(next);
    setCurrentMessages(messages[next]!);
    localStorage.setItem(STORAGE_KEY, next);
    try {
      const res = await fetch("/api/v1/users/me", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ locale: next }),
      });
      if (!res.ok) throw new Error("Failed to save locale");
      return true;
    } catch {
      // Revert on failure so the UI doesn't claim a language that never saved.
      setLocaleState(previous);
      setCurrentMessages(previousMessages);
      localStorage.setItem(STORAGE_KEY, previous);
      return false;
    }
  }

  return (
    <LocaleContext.Provider value={{ locale, setLocale }}>
      <NextIntlClientProvider locale={locale} messages={currentMessages} timeZone="UTC">
        {children}
      </NextIntlClientProvider>
    </LocaleContext.Provider>
  );
}
