import type { ChatMessage } from '@genesislcap/foundation-ai';
import DOMPurify from 'dompurify';
import { sumUsage, totalTokens } from './sum-usage';

/**
 * Total tokens across a message list — the headline figure, with the per-bucket
 * split available from {@link sumUsage} for anything that needs to show *why* a
 * large token count cost little.
 *
 * Identical arithmetic to the old per-message `inputTokens + outputTokens` sum:
 * the three input buckets partition `inputTokens`, so they re-add to it exactly.
 * It does now additionally count usage banked by a compaction, which is the point
 * — that spend used to vanish when the summarised turns left the transcript.
 *
 * Returns 0 when no message carries token metadata.
 *
 * @internal
 */
export function sumTokens(messages: readonly ChatMessage[]): number {
  return totalTokens(sumUsage(messages));
}

const TOKEN_SCALE_DECIMAL_FACTOR = 10;
const TOKENS_PER_MILLION = 1_000_000;
const TOKENS_PER_THOUSAND = 1_000;
const SUFFIX_ROLLOVER_THRESHOLD = 1000;

const roundScaled = (scaled: number): number =>
  Math.round(scaled * TOKEN_SCALE_DECIMAL_FACTOR) / TOKEN_SCALE_DECIMAL_FACTOR;

const formatScaledTokenMarkup = (rounded: number, suffix: string): string => {
  const value = Number.isInteger(rounded) ? String(rounded) : rounded.toFixed(1);
  return `<span class="value">${value}</span><span class="suffix">${suffix}</span>`;
};

const scaledSuffixLabel = (tokens: number): string | undefined => {
  if (tokens >= TOKENS_PER_MILLION) return 'M';
  if (tokens >= TOKENS_PER_THOUSAND) {
    const kRounded = roundScaled(tokens / TOKENS_PER_THOUSAND);
    if (kRounded >= SUFFIX_ROLLOVER_THRESHOLD) return 'M';
    return 'K';
  }
  return undefined;
};

const scaledNumericValue = (tokens: number): number | undefined => {
  const suffix = scaledSuffixLabel(tokens);
  if (!suffix) return undefined;
  if (suffix === 'M') return roundScaled(tokens / TOKENS_PER_MILLION);
  return roundScaled(tokens / TOKENS_PER_THOUSAND);
};

/**
 * Compact display for large token counts (e.g. 1_400_000 → value "1.4" + suffix "M").
 * Returns HTML markup so the suffix can be styled separately in the settings modal.
 *
 * @internal
 */
export function formatCompactTokenCount(tokens: number): string {
  const suffix = scaledSuffixLabel(tokens);
  if (!suffix) return tokens.toLocaleString();
  return formatScaledTokenMarkup(scaledNumericValue(tokens)!, suffix);
}

/** {@link formatCompactTokenCount} passed through DOMPurify for `:innerHTML` bindings. */
export function formatCompactTokenCountSafe(tokens: number): string {
  return DOMPurify.sanitize(formatCompactTokenCount(tokens));
}
