import {
  AmountJson,
  Amounts,
  CurrencySpecification,
} from "@gnu-taler/taler-util";
import { h, VNode } from "preact";

/**
 * Common way to render amount
 *
 * @param value the amount to be rendered
 * @param spec currency specification
 * @param specMap currency specification by currency name
 * @param hideSmall don't show very tiny value
 * @param negative if the value specified by amount is negative
 * @param withColor show negative as red and positive as green
 * @param withSign include a minus for negatives
 * @returns
 */
export function RenderAmount({
  value,
  spec,
  specMap,
  negative,
  withColor,
  withSign,
  hideSmall,
}: {
  spec?: CurrencySpecification;
  specMap?: Record<string, CurrencySpecification>;
  value: AmountJson;
  hideSmall?: boolean;
  negative?: boolean;
  withColor?: boolean;
  withSign?: boolean;
}): VNode {
  const neg = !!negative; // convert to true or false

  const currentSpec = spec ?? (!specMap ? undefined : specMap[value.currency]);
  if (!currentSpec) {
    throw Error("missing currency spec");
  }
  const { currency, normal, small } = Amounts.stringifyValueWithSpec(
    value,
    currentSpec,
  );

  return (
    <span
      data-negative={withColor ? neg : undefined}
      class="whitespace-nowrap data-[negative=false]:text-green-600 data-[negative=true]:text-red-600"
    >
      {withSign && negative ? "- " : undefined}
      {currency} {normal}{" "}
      {!hideSmall && small && <sup class="-ml-1">{small}</sup>}
    </span>
  );
}

export function RenderAmountBulma({
  value,
  spec,
  specMap,
  negative,
  withColor,
  withSign,
  hideSmall,
}: {
  spec?: CurrencySpecification;
  specMap?: Record<string, CurrencySpecification>;
  value: AmountJson;
  hideSmall?: boolean;
  negative?: boolean;
  withColor?: boolean;
  withSign?: boolean;
}): VNode {
  const neg = !!negative;

  const currentSpec = spec ?? (!specMap ? undefined : specMap[value.currency]);
  if (!currentSpec) {
    throw Error("missing currency spec");
  }

  const { currency, normal, small } = Amounts.stringifyValueWithSpec(
    value,
    currentSpec,
  );

  return (
    <span
      data-negative={withColor ? neg : undefined}
      style={{
        whiteSpace: "nowrap",
        color: withColor ? (negative ? "red" : "green") : undefined,
      }}
    >
      {withSign && negative ? "- " : undefined}
      {currency} {normal}{" "}
      {!hideSmall && small && <sup style={{ marginLeft: -4 }}>{small}</sup>}
    </span>
  );
}
