/**
 * TextAlign — approximate column alignment for Discord embeds using
 * invisible filler characters (ㅤ U+3164 Hangul Filler).
 *
 * Discord embed text is NOT monospace, so naive character-count padding
 * misaligns whenever strings contain narrow characters (punctuation,
 * symbols like »«) mixed with regular letters. This module estimates
 * VISUAL width per character (not raw count) for better alignment.
 *
 * EXPERIMENTAL — width weights are approximations tuned by visual
 * comparison in actual Discord clients, not measured font metrics.
 * Iterate WIDTH_TABLE based on screenshots.
 *
 * Usage:
 *   import { TextAlign } from "@ui/text-align";
 *
 *   const width = TextAlign.estimateWidth("»Flash«");
 *   const padded = TextAlign.pad("»Flash«", maxWidth);
 *   const maxWidth = TextAlign.maxWidth(["»Flash«", "XefronYokuda", ...]);
 */

import { Logger } from "../systems/logger";

 const log = Logger.for("TextAlign");

 const FILLER = "\u2009"; // Thin Space — finer-grained than Hangul Filler, better precision

 // ─── Width estimation ──────────────────────────────────────────────────────
 // Flat character width (1.0) for ALL characters, including guillemets.
 // IMPORTANT: guillemet narrowness is already implicitly absorbed into the
 // FILLERS_PER_CHAR calibration below (calibrated using names that included
 // guillemets). Adding a SEPARATE per-character guillemet correction here
 // double-counts the effect and causes overcorrection. Do not reintroduce
 // without recalibrating FILLERS_PER_CHAR from scratch using guillemet-free
 // reference names only.
 function charWidth(ch: string): number {
   return 1.0;
 }
 
 // Estimated width of the invisible filler character itself, relative to
 // one standard letter, SPECIFICALLY INSIDE EMBEDS using Thin Space (U+2009).
 // CALIBRATED via live embed testing:
 //   «Keira» (7) vs XefronYokuda (12), diff 5 chars — exactly 14 thin fillers
 //   »No.1« (6) vs «MonkeyHunter» (14), diff 8 chars — exactly 23 thin fillers
 // Combined: 37 fillers per 13 missing chars => 1 char ≈ 2.846 fillers
 const FILLERS_PER_CHAR = 37 / 13; // ≈ 2.846
 const FILLER_WIDTH = 1 / FILLERS_PER_CHAR; // ≈ 0.351 (letter-widths per filler)
 
 // ─── Namespace ────────────────────────────────────────────────────────────────
 
 export const TextAlign = {
   /**
    * Estimate the visual width of a string in "units" (1.0 = one average letter).
    */
   estimateWidth(text: string): number {
     return text.split("").reduce((sum, ch) => sum + charWidth(ch), 0);
   },
 
   /**
    * Get the max estimated width across a list of strings.
    */
   maxWidth(texts: string[]): number {
     return Math.max(...texts.map((t) => TextAlign.estimateWidth(t)), 0);
   },
 
   /**
    * Pad a string with invisible filler characters to reach a target width.
    */
   pad(text: string, targetWidth: number): string {
     const current = TextAlign.estimateWidth(text);
     const diff    = targetWidth - current;
     if (diff <= 0) return text;
     const fillerCount = Math.round(diff / FILLER_WIDTH);
     log.info(`[TextAlign] "${text}": estimatedWidth=${current.toFixed(3)} target=${targetWidth.toFixed(3)} diff=${diff.toFixed(3)} fillerCount=${fillerCount}`);
     return text + FILLER.repeat(Math.max(0, fillerCount));
   },
 
   /**
    * Pad a string to match the widest string in a list (convenience).
    */
   padToMax(text: string, allTexts: string[]): string {
     return TextAlign.pad(text, TextAlign.maxWidth(allTexts));
   },
 };