"use client";

import { createContext, useContext, useEffect, useState } from "react";

// ── Theme ────────────────────────────────────────────────────────────────────

type Theme = "dark" | "light";

const ThemeContext = createContext<{ theme: Theme; toggle: () => void }>({
  theme: "dark",
  toggle: () => {},
});

export function useTheme() {
  return useContext(ThemeContext);
}

// ── Currency ─────────────────────────────────────────────────────────────────

export type Currency = "usd" | "lkr" | "eur";

export type Prices = { usd: number; lkr: number; eur: number };

const CURRENCY_META: Record<Currency, { symbol: string; label: string; decimals: number }> = {
  usd: { symbol: "$", label: "USD", decimals: 2 },
  lkr: { symbol: "Rs.", label: "LKR", decimals: 0 },
  eur: { symbol: "€", label: "EUR", decimals: 2 },
};

const CurrencyContext = createContext<{
  currency: Currency;
  setCurrency: (c: Currency) => void;
  format: (prices: Prices) => string;
  meta: (typeof CURRENCY_META)[Currency];
}>({
  currency: "usd",
  setCurrency: () => {},
  format: (p) => `$${p.usd.toFixed(2)}`,
  meta: CURRENCY_META.usd,
});

export function useCurrency() {
  return useContext(CurrencyContext);
}

// Countries that use EUR (EU members + eurozone non-EU)
const EUR_COUNTRIES = new Set([
  "AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR",
  "DE","GR","HU","IE","IT","LV","LT","LU","MT","NL",
  "PL","PT","RO","SK","SI","ES","SE",
  // Eurozone non-EU
  "AD","MC","SM","VA","ME","XK",
]);

async function detectCurrency(): Promise<Currency> {
  try {
    const res = await fetch("https://ipapi.co/json/", { signal: AbortSignal.timeout(4000) });
    if (!res.ok) return "usd";
    const data = await res.json();
    const cc: string = data.country_code ?? "";
    if (cc === "LK") return "lkr";
    if (EUR_COUNTRIES.has(cc)) return "eur";
    return "usd";
  } catch {
    return "usd";
  }
}

// ── Combined Providers ────────────────────────────────────────────────────────

export default function Providers({ children }: { children: React.ReactNode }) {
  const [theme, setTheme] = useState<Theme>("dark");
  const [currency, setCurrency] = useState<Currency>("usd");
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    const savedTheme = (localStorage.getItem("p2m-theme") as Theme) ?? "dark";
    setTheme(savedTheme);

    const savedCurrency = localStorage.getItem("p2m-currency") as Currency | null;
    if (savedCurrency) {
      // User previously chose manually — honour it
      setCurrency(savedCurrency);
      setMounted(true);
    } else {
      // First visit — auto-detect from IP
      detectCurrency().then((detected) => {
        setCurrency(detected);
        localStorage.setItem("p2m-currency", detected);
        setMounted(true);
      });
    }
  }, []);

  useEffect(() => {
    if (!mounted) return;
    const html = document.documentElement;
    if (theme === "light") {
      html.classList.add("light");
      html.classList.remove("dark");
    } else {
      html.classList.remove("light");
      html.classList.add("dark");
    }
    localStorage.setItem("p2m-theme", theme);
  }, [theme, mounted]);

  const handleSetCurrency = (c: Currency) => {
    setCurrency(c);
    localStorage.setItem("p2m-currency", c);
  };

  const toggle = () => setTheme((t) => (t === "dark" ? "light" : "dark"));

  const format = (prices: Prices): string => {
    const m = CURRENCY_META[currency];
    const val = prices[currency];
    return `${m.symbol}${m.decimals === 0 ? Math.round(val).toLocaleString() : val.toFixed(m.decimals)}`;
  };

  return (
    <ThemeContext.Provider value={{ theme, toggle }}>
      <CurrencyContext.Provider value={{ currency, setCurrency: handleSetCurrency, format, meta: CURRENCY_META[currency] }}>
        {children}
      </CurrencyContext.Provider>
    </ThemeContext.Provider>
  );
}
