"use client";

import { getPublicSettings, type SettingItem } from "@/api/settings";

export type CurrencyDisplayFormat = {
  displayDecimals: number;
  decimalSeparator: string;
  thousandsSeparator: string;
};

const DEFAULT_FORMAT: CurrencyDisplayFormat = {
  displayDecimals: 2,
  decimalSeparator: ".",
  thousandsSeparator: ",",
};

const SETTINGS_TTL_MS = 60_000;

let cachedFormat: CurrencyDisplayFormat | null = null;
let fetchedAt = 0;
let pendingLoad: Promise<CurrencyDisplayFormat> | null = null;

function parseFormatFromItems(items: SettingItem[]): CurrencyDisplayFormat {
  const byKey = new Map(items.map((item) => [item.key, item.value]));

  const rawDecimals = byKey.get("currency.display_decimals");
  const displayDecimals =
    typeof rawDecimals === "number" && Number.isFinite(rawDecimals)
      ? Math.max(0, Math.min(12, Math.trunc(rawDecimals)))
      : DEFAULT_FORMAT.displayDecimals;

  const decimalSeparator =
    typeof byKey.get("currency.decimal_separator") === "string"
      ? (byKey.get("currency.decimal_separator") as string)
      : DEFAULT_FORMAT.decimalSeparator;

  const thousandsSeparator =
    typeof byKey.get("currency.thousands_separator") === "string"
      ? (byKey.get("currency.thousands_separator") as string)
      : DEFAULT_FORMAT.thousandsSeparator;

  return {
    displayDecimals,
    decimalSeparator,
    thousandsSeparator,
  };
}

function isCacheFresh(): boolean {
  return cachedFormat !== null && Date.now() - fetchedAt < SETTINGS_TTL_MS;
}

export function getCurrencyDisplayFormat(): CurrencyDisplayFormat {
  return cachedFormat ?? DEFAULT_FORMAT;
}

export function invalidateCurrencyDisplayFormat(): void {
  cachedFormat = null;
  fetchedAt = 0;
  pendingLoad = null;
}

export async function loadCurrencyDisplayFormat(
  force = false,
): Promise<CurrencyDisplayFormat> {
  if (!force && isCacheFresh()) {
    return getCurrencyDisplayFormat();
  }

  pendingLoad ??= getPublicSettings("currency")
    .then((response) => {
      cachedFormat = parseFormatFromItems(response.items);
      fetchedAt = Date.now();
      return cachedFormat;
    })
    .catch((error: unknown) => {
      console.warn(
        "[CurrencyDisplay] Failed to load public currency settings:",
        error,
      );
      return getCurrencyDisplayFormat();
    })
    .finally(() => {
      pendingLoad = null;
    });

  return pendingLoad;
}
