"use client";

import React, { createContext, useContext, useState, useEffect } from "react";
import { api } from "@/lib/api";
import { Settings } from "@/types";

interface SettingsContextType {
  settings: Settings | null;
  loading: boolean;
  currency: string;
  currencyCode: string;
  language: string;
  locale: string;
  setCurrencyCode: (code: string) => void;
  setLanguage: (lang: string) => void;
  formatMoney: (amount: number) => string;
}

const SettingsContext = createContext<SettingsContextType | undefined>(undefined);

export function SettingsProvider({ children }: { children: React.ReactNode }) {
  const [settings, setSettings] = useState<Settings | null>(null);
  const [loading, setLoading] = useState(true);
  const [currencyCode, setCurrencyCodeState] = useState("USD");
  const [language, setLanguageState] = useState("English");
  const [baseCurrencyCode, setBaseCurrencyCode] = useState("USD");
  const [usdToBdtRate, setUsdToBdtRate] = useState<number | null>(null);

  useEffect(() => {
    // Load persisted preferences first
    try {
      const savedCurrency = typeof window !== "undefined" ? localStorage.getItem("currencyCode") : null;
      const savedLanguage = typeof window !== "undefined" ? localStorage.getItem("language") : null;
      if (savedCurrency) setCurrencyCodeState(savedCurrency);
      if (savedLanguage) setLanguageState(savedLanguage);
    } catch {}

    const fetchSettings = async () => {
      try {
        const response = await api.getSettings();
        if (response.data) {
          setSettings(response.data);
          // Only apply server defaults if user hasn't chosen explicitly
          const hasUserCurrency = typeof window !== "undefined" && !!localStorage.getItem("currencyCode");
          const hasUserLanguage = typeof window !== "undefined" && !!localStorage.getItem("language");
          if (response.data.currency_code && !hasUserCurrency) setCurrencyCodeState(response.data.currency_code);
          if (response.data.default_language && !hasUserLanguage) setLanguageState(response.data.default_language);
          if (response.data.base_currency_code) setBaseCurrencyCode(response.data.base_currency_code);
          if (response.data.usd_to_bdt_rate) {
            const r = parseFloat(response.data.usd_to_bdt_rate as unknown as string);
            if (Number.isFinite(r) && r > 0) setUsdToBdtRate(r);
          }
        }
        // If user is logged in, prefer their saved preferences
        if (typeof window !== "undefined") {
          const token = localStorage.getItem("auth_token");
          if (token) {
            try {
              const me = await api.getUser(token);
              const u = (me as any)?.data;
              const userCurrency = u?.preferred_currency_code;
              const userLanguage = u?.preferred_language;
              if (userCurrency) {
                setCurrencyCodeState(userCurrency);
                localStorage.setItem("currencyCode", userCurrency);
              }
              if (userLanguage) {
                setLanguageState(userLanguage);
                localStorage.setItem("language", userLanguage);
              }
            } catch {
              // ignore
            }
          }
        }
      } catch (error) {
        // Silently fail or log a simple warning
        console.warn("Failed to fetch settings, using default values.");
      } finally {
        setLoading(false);
      }
    };

    fetchSettings();
  }, []);

  // Persist changes
  useEffect(() => {
    try {
      if (typeof window !== "undefined") localStorage.setItem("currencyCode", currencyCode);
    } catch {}
  }, [currencyCode]);

  useEffect(() => {
    try {
      if (typeof window !== "undefined") localStorage.setItem("language", language);
    } catch {}
  }, [language]);

  // Symbol should reflect the currently selected code, not always server default
  const currency = (() => {
    if (currencyCode === "BDT") return "৳";
    if (currencyCode === "USD") return "$";
    // Fallback to server symbol or code itself
    return settings?.currency_symbol || currencyCode;
  })();
  const locale = language === "Bengali" ? "bn-BD" : "en-US";

  const setCurrencyCode = (code: string) => {
    setCurrencyCodeState(code);
    // Persist to DB if logged-in
    try {
      api.updateProfile({ preferred_currency_code: code });
    } catch {}
  };
  const setLanguage = (lang: string) => {
    setLanguageState(lang);
    try {
      api.updateProfile({ preferred_language: lang });
    } catch {}
  };

  const convertAmount = (amount: number, from: string, to: string) => {
    if (!amount || from === to) return amount;
    // Basic USD <-> BDT conversion controlled by admin rate
    if ((from === "USD" && to === "BDT") && usdToBdtRate) return amount * usdToBdtRate;
    if ((from === "BDT" && to === "USD") && usdToBdtRate) return amount / usdToBdtRate;
    // Unknown pair: no conversion
    return amount;
  };

  const formatMoney = (amount: number) => {
    try {
      const base = baseCurrencyCode || "USD";
      const converted = convertAmount(amount, base, currencyCode);
      // Prefer explicit currency formatting for precision
      return new Intl.NumberFormat(locale, {
        style: "currency",
        currency: currencyCode || "USD",
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
      }).format(converted);
    } catch {
      // Fallback
      const base = baseCurrencyCode || "USD";
      const converted = convertAmount(amount, base, currencyCode);
      return `${currency}${converted.toFixed(2)}`;
    }
  };

  return (
    <SettingsContext.Provider value={{ 
      settings, 
      loading, 
      currency, 
      currencyCode, 
      language,
      locale,
      setCurrencyCode,
      setLanguage,
      formatMoney,
    }}>
      {children}
    </SettingsContext.Provider>
  );
}

export function useSettings() {
  const context = useContext(SettingsContext);
  if (context === undefined) {
    throw new Error("useSettings must be used within a SettingsProvider");
  }
  return context;
}
