import { openStore } from "@/lib/data/store";
import type { GatewaySettings } from "@/lib/types";

/**
 * Exchange rates, so a price can be shown in the reader's own money.
 *
 * The site's currency is the real one: everything is stored and charged in
 * it. A converted figure is a courtesy for the reader, always shown as an
 * approximation, and never what anyone is actually charged.
 */

/** Rates are fetched once a day; they don't move enough to matter more often. */
const REFRESH_AFTER = 24 * 3600_000;

type Rates = { base: string; fetchedAt: number; rates: Record<string, number> };

let cache: Rates | null = null;
let inFlight: Promise<Rates | null> | null = null;

/**
 * Today's rates against the site's currency, or null when they can't be
 * reached. Callers must handle null by showing the original price — a
 * missing rate should never invent a number.
 */
export async function ratesFor(base: string): Promise<Rates | null> {
  if (cache && cache.base === base && Date.now() - cache.fetchedAt < REFRESH_AFTER) {
    return cache;
  }

  // One request at a time, however many callers ask.
  if (inFlight) return inFlight;

  inFlight = (async () => {
    try {
      // Frankfurter is the European Central Bank's daily reference rates.
      // No key, no account, and it doesn't rate-limit ordinary use.
      const res = await fetch(
        `https://api.frankfurter.app/latest?from=${encodeURIComponent(base)}`,
        { headers: { Accept: "application/json" } }
      );
      if (!res.ok) return null;

      const data = await res.json();
      if (!data?.rates) return null;

      cache = { base, fetchedAt: Date.now(), rates: data.rates };
      return cache;
    } catch {
      // Offline, or the service is down. The price still shows correctly
      // in the site's own currency.
      return null;
    } finally {
      inFlight = null;
    }
  })();

  return inFlight;
}

/** Whether the admin has switched local prices on. */
export async function conversionSettings() {
  const store = await openStore();
  const s = await store.settings();
  const gateways = await store.small<GatewaySettings>("gateways", {} as GatewaySettings);
  return {
    enabled: s.showLocalPrices === true,
    base: String(gateways.currency ?? "USD"),
  };
}
