import { getCachedAdminCurrencies } from "@/hooks/use-admin-currency-catalog";

const DEFAULT_DECIMAL_PLACES = 2;

/** 接口缺字段或非数字时按 0 处理，避免仪表盘出现 NPRNaN */
export function coerceAdminMinor(value: unknown): number {
  const n = typeof value === "number" ? value : Number(value);
  if (!Number.isFinite(n)) {
    return 0;
  }
  return Math.trunc(n);
}

export function getAdminCurrencyDecimalPlaces(currencyCode: string | null | undefined): number {
  const code = currencyCode?.trim().toUpperCase();
  if (!code) {
    return DEFAULT_DECIMAL_PLACES;
  }

  const row = getCachedAdminCurrencies().find((item) => item.code === code);
  const decimals = row?.decimal_places;
  if (typeof decimals === "number" && Number.isFinite(decimals) && decimals >= 0) {
    return decimals;
  }

  return DEFAULT_DECIMAL_PLACES;
}

/** 后台列表统一：最小货币单位 → 主货币展示（默认 2 位小数，与钱包一致） */
export function formatAdminMinorUnits(
  minor: number,
  currencyCode = "NPR",
  decimalPlaces?: number,
): string {
  const safeMinor = coerceAdminMinor(minor);
  const resolvedDecimalPlaces =
    typeof decimalPlaces === "number" && Number.isFinite(decimalPlaces) && decimalPlaces >= 0
      ? decimalPlaces
      : getAdminCurrencyDecimalPlaces(currencyCode);
  const major = safeMinor / 10 ** resolvedDecimalPlaces;
  return `${currencyCode} ${major.toLocaleString(undefined, {
    minimumFractionDigits: resolvedDecimalPlaces,
    maximumFractionDigits: resolvedDecimalPlaces,
  })}`;
}

/**
 * 信用占成盘授信/已下发/可用额度：库内为主货币整数（与后台录入一致），展示带小数位。
 */
export function formatAdminCreditMajor(
  major: number,
  currencyCode = "NPR",
  decimalPlaces?: number,
): string {
  const safeMajor = Number.isFinite(major) ? major : 0;
  const resolvedDecimalPlaces =
    typeof decimalPlaces === "number" && Number.isFinite(decimalPlaces) && decimalPlaces >= 0
      ? decimalPlaces
      : getAdminCurrencyDecimalPlaces(currencyCode);

  return `${currencyCode} ${safeMajor.toLocaleString(undefined, {
    minimumFractionDigits: resolvedDecimalPlaces,
    maximumFractionDigits: resolvedDecimalPlaces,
  })}`;
}

/** 授信额度展示（无币种前缀，用于代理概要卡片等）。 */
export function formatAdminCreditMajorDecimal(
  major: number,
  currencyCode = "NPR",
  decimalPlaces?: number,
): string {
  const safeMajor = Number.isFinite(major) ? major : 0;
  const resolvedDecimalPlaces =
    typeof decimalPlaces === "number" && Number.isFinite(decimalPlaces) && decimalPlaces >= 0
      ? decimalPlaces
      : getAdminCurrencyDecimalPlaces(currencyCode);

  return safeMajor.toLocaleString(undefined, {
    minimumFractionDigits: resolvedDecimalPlaces,
    maximumFractionDigits: resolvedDecimalPlaces,
  });
}

export function formatAdminMinorDecimal(
  minor: number,
  currencyCode = "NPR",
  decimalPlaces?: number,
): string {
  const resolvedDecimalPlaces =
    typeof decimalPlaces === "number" && Number.isFinite(decimalPlaces) && decimalPlaces >= 0
      ? decimalPlaces
      : getAdminCurrencyDecimalPlaces(currencyCode);
  const major = minor / 10 ** resolvedDecimalPlaces;
  return major.toLocaleString(undefined, {
    minimumFractionDigits: resolvedDecimalPlaces,
    maximumFractionDigits: resolvedDecimalPlaces,
  });
}

export function parseAdminMajorToMinor(
  raw: string,
  currencyCode = "NPR",
  decimalPlaces?: number,
): number | null {
  const resolvedDecimalPlaces =
    typeof decimalPlaces === "number" && Number.isFinite(decimalPlaces) && decimalPlaces >= 0
      ? decimalPlaces
      : getAdminCurrencyDecimalPlaces(currencyCode);
  const cleaned = raw.replace(/,/g, "").trim();
  if (!cleaned) return null;
  const n = Number(cleaned);
  if (!Number.isFinite(n) || n < 0) return null;
  const factor = 10 ** resolvedDecimalPlaces;
  const minor = Math.round(n * factor);
  return Number.isSafeInteger(minor) ? minor : null;
}

export function parseSignedAdminMajorToMinor(
  raw: string,
  currencyCode = "NPR",
  decimalPlaces?: number,
): number | null {
  const cleaned = raw.replace(/,/g, "").trim();
  if (!cleaned) {
    return null;
  }

  const n = Number(cleaned);
  if (!Number.isFinite(n) || n === 0) {
    return null;
  }

  const absMinor = parseAdminMajorToMinor(String(Math.abs(n)), currencyCode, decimalPlaces);
  if (absMinor === null) {
    return null;
  }

  return n < 0 ? -absMinor : absMinor;
}
