"use client";

import { useCurrency } from "./useCurrency";
import { FALLBACK_CURRENCY } from "@customer-portal/domain/billing";
import { Formatting } from "@customer-portal/domain/toolkit";

export type FormatCurrencyOptions = {
  currency?: string;
  currencySymbol?: string;
  locale?: string;
  showSymbol?: boolean;
};

const isOptions = (
  value: string | FormatCurrencyOptions | undefined
): value is FormatCurrencyOptions => {
  return typeof value === "object" && value !== null;
};

function pickFirst<T>(a: T | undefined, b: T | undefined): T | undefined {
  return a || b;
}

function resolveShowSymbol(
  opts: FormatCurrencyOptions | undefined,
  fallback: FormatCurrencyOptions | undefined
): boolean | undefined {
  if (opts && typeof opts.showSymbol === "boolean") return opts.showSymbol;
  return fallback?.showSymbol;
}

function resolveOptions(
  currencyOrOptions: string | FormatCurrencyOptions | undefined,
  options: FormatCurrencyOptions | undefined
): { currency?: string; currencySymbol?: string; locale?: string; showSymbol?: boolean } {
  const opts = isOptions(currencyOrOptions) ? currencyOrOptions : undefined;
  const strCurrency = typeof currencyOrOptions === "string" ? currencyOrOptions : undefined;

  const currency = strCurrency || pickFirst(opts?.currency, options?.currency);
  const currencySymbol = pickFirst(opts?.currencySymbol, options?.currencySymbol);
  const locale = pickFirst(opts?.locale, options?.locale);
  const showSymbol = resolveShowSymbol(opts, options);

  const result: {
    currency?: string;
    currencySymbol?: string;
    locale?: string;
    showSymbol?: boolean;
  } = {};
  if (currency !== undefined) result.currency = currency;
  if (currencySymbol !== undefined) result.currencySymbol = currencySymbol;
  if (locale !== undefined) result.locale = locale;
  if (showSymbol !== undefined) result.showSymbol = showSymbol;
  return result;
}

export function useFormatCurrency() {
  const { currencyCode, currencySymbol, loading, error } = useCurrency();

  const formatCurrency = (
    amount: number,
    currencyOrOptions?: string | FormatCurrencyOptions,
    options?: FormatCurrencyOptions
  ) => {
    const fallbackCurrency = currencyCode ?? FALLBACK_CURRENCY.code;
    const fallbackSymbol = currencySymbol ?? FALLBACK_CURRENCY.prefix;
    const resolved = resolveOptions(currencyOrOptions, options);

    return Formatting.formatCurrency(amount, resolved.currency ?? fallbackCurrency, {
      currencySymbol: resolved.currencySymbol ?? fallbackSymbol,
      locale: resolved.locale,
      showSymbol: resolved.showSymbol,
    });
  };

  return { formatCurrency, currencyCode, loading, error };
}
