// The words and numbers of the Quantities results, in the shopper's language. Used by quantities-core.ts
// in the worker. English text is word for word what the planner wrote before translations; other
// languages come from the catalogue the element sends with each request (src/i18n/quantities/core-*.ts).

import { core as english, type QuantitiesCoreKey, type QuantitiesCoreMessages } from "./i18n/quantities/core-en";
import type { DisplayUnits } from "./config";
import { formatCubic } from "./format";
import { createTranslator, SOURCE_LANGUAGE, type Params } from "./i18n/translate";
import { translateEnglish } from "./i18n/translate-english";
import { Measures } from "./quantities-measures";

// English that shared code writes (lib/tile.ts, lib/wallpaper.ts, src/materials.ts), found by its template.
// ("term." keys are words inside those messages, not messages, so they are not matched as text.)
const SHARED_KEYS = (Object.keys(english) as QuantitiesCoreKey[]).filter((key) => key.startsWith("lib.") || key.startsWith("error."));

export class CoreText extends Measures {
  constructor(lang: string = SOURCE_LANGUAGE, messages: QuantitiesCoreMessages | typeof english = english) {
    super(createTranslator(lang, messages, english));
  }

  t(key: QuantitiesCoreKey, params?: Params): string {
    return this.tr.t(key, params);
  }

  /** A number the shop or shopper gave ("7.5" for an allowance), in the language's way ("7,5"). */
  number(value: number): string {
    return this.english ? String(value) : this.tr.decimal(value, 3);
  }

  /** The volume of an area at a depth: "0.3 m³" or "10.6 cu ft". */
  cubic(mm3: number, u: DisplayUnits): string {
    return this.local(formatCubic(mm3, u));
  }

  /** English from shared code (lib/tile.ts, lib/wallpaper.ts, src/materials.ts), translated when known. */
  shared(text: string): string {
    return translateEnglish(text, this.tr, english, SHARED_KEYS, (value) => this.sharedValue(value));
  }

  /** A placeholder's English inside shared code's text: "100,000", "Wall 2" or "Room width". */
  private sharedValue(value: string): string {
    if (/^\d+$|^\d{1,3}(?:,\d{3})+$/.test(value)) return this.tr.count(Number(value.replace(/,/g, "")));
    const wall = /^Wall (\d+)$/.exec(value);
    if (wall) return this.t("term.wall", { number: Number(wall[1]) });
    if (value === english["term.roomWidth"]) return this.t("term.roomWidth");
    if (value === english["term.roomLength"]) return this.t("term.roomLength");
    return value;
  }
}

export const ENGLISH_CORE = new CoreText();
