import { Character, ClassKey, CharacterClass, Nation, WRankEntry } from "@src/types";
import { Emoji } from "@systems/emojis";

// ─── Individual formatters ────────────────────────────────────────────────────

export interface CharDisplayOptions {
  emoji?: boolean;  // show class emoji (default: true)
  level?: boolean;  // show level (default: true)
}

function charButton(c: Character, options?: { shared?: boolean }): string {
  const sharedMark = options?.shared ? " 🔗" : "";
  return `${c.level} ${c.name}${sharedMark}`;
}

/**
 * Format a character for display in embeds and messages.
 * Output: <:class:> 79 «Flash»
 */
function char(
  c: { class: ClassKey|CharacterClass; level: number; name: string },
  options?: CharDisplayOptions
): string {
  const showEmoji = options?.emoji ?? true;
  const showLevel = options?.level ?? true;
  const classStr  = showEmoji ? (Emoji.class(c.class) || c.class) : c.class;
  const levelStr  = showLevel ? `${c.level} ` : "";
  return `${classStr} ${levelStr}${c.name}`.trim();
}

/**
 * Format a nation name with its emoji.
 * Output: <:capella:> Capella
 */
function nation(n: Nation): string {
  const emoji = Emoji.nation(n);
  return emoji ? `${emoji} ${n}` : n;
}

/**
 * Format a score line.
 * Output: <:score:> 3000 <:kd:> 32/18
 */
function score(pts: number, k?: number, d?: number): string {
  const scoreEmoji = Emoji.get("score") || "📊";
  const kdEmoji    = Emoji.get("kd")    || "⚔️";
  const kdStr      = k !== undefined && d !== undefined ? ` ${kdEmoji} ${k}/${d}` : "";
  return `${scoreEmoji} ${pts}${kdStr}`;
}

/**
 * Parse a Discord custom emoji string to an object for ButtonBuilder.setEmoji()
 * Input: "<:fb:1511020923510194428>"
 * Output: { name: "fb", id: "1511020923510194428" }
 */
function emoji(emojiStr: string): { name: string; id: string } | string | null {
  if (!emojiStr) return null;
  const match = emojiStr.match(/^<:(\w+):(\d+)>$/);
  if (match) return { name: match[1], id: match[2] };
  return emojiStr;
}

// ─── W.Rank formatters ────────────────────────────────────────────────────────

export interface WRankDisplayOptions {
  goal:         number;
  brackets?:    boolean;  // wrap delta in parentheses (default: true)
}

/**
 * Format the rank indicator for a wrank entry.
 * Output: <:wrank_1_gold:> or <:wrank_1:> or bold/plain number fallback
 */
function wrankRank(entry: WRankEntry, goal: number): string {
  const isDone   = entry.tgCount >= goal;
  const rankKey  = isDone ? `wrank_${entry.currentRank}_gold` : `wrank_${entry.currentRank}`;
  return Emoji.get(rankKey) || (isDone ? `**${entry.currentRank}**` : `${entry.currentRank}`);
}

/**
 * Format the delta indicator for a wrank entry.
 * Output: <:wrank_up:><:wrank_up_2:> or ↑2, empty string if no change
 */
function wrankDelta(entry: WRankEntry, options?: { brackets?: boolean }): string {
  const brackets  = options?.brackets ?? true;
  const prev      = entry.previousRank;
  const delta     = prev !== undefined ? entry.currentRank - prev : 0;

  if (delta === 0 && prev === undefined) return "";

  let inner: string;
  if (delta < 0) {
    const abs      = Math.abs(delta);
    const numEmoji = Emoji.get(`wrank_up_${abs}`);
    inner = (Emoji.get("wrank_up") || "↑") + (numEmoji || abs);
  } else if (delta > 0) {
    const numEmoji = Emoji.get(`wrank_down_${delta}`);
    inner = (Emoji.get("wrank_down") || "↓") + (numEmoji || delta);
  } else {
    inner = (Emoji.get("wrank_no_dash") || "·") + (Emoji.get("wrank_neutral_0") || "0");
  }

  return brackets ? ` (${inner})` : ` ${inner}`;
}

/**
 * Format a full wrank display string: rank + delta.
 * Output: <:wrank_1_gold:> (<:wrank_up:><:wrank_up_2:>)
 */
function wrankFull(entry: WRankEntry, options: WRankDisplayOptions): string {
  return wrankRank(entry, options.goal) + wrankDelta(entry, { brackets: options.brackets });
}

/**
 * Placeholder for characters with no W.Rank when others in their nation have one.
 * Output: — ( — 0 )
 */
 function wrankNoRank(): string {
  const norank = Emoji.get("wrank_no_dash")  || "—";
  const dash   = Emoji.get("wrank_no_rank_delta")  || "—";
  const square = Emoji.get("wrank_no_dash")  || "■";
  return `${norank} (${square}${dash})`;
}

// ─── Bringer formatters ────────────────────────────────────────────────────────

function bringerDisplay(n: Nation): string {
  const bringerMap: Record<Nation, string> = {
    Capella: Emoji.get("luminous_bringer") || "🔆 Luminous Bringer",
    Procyon: Emoji.get("storm_bringer")    || "⚡ Storm Bringer",
  };
  return bringerMap[n];
}

// ─── Namespace export ─────────────────────────────────────────────────────────

export const format = {
  char,
  charButton,
  nation,
  score,
  emoji,
  wrank: {
    rank:  wrankRank,
    delta: wrankDelta,
    full:  wrankFull,
    noRank: wrankNoRank,
  },
  bringer: bringerDisplay,
};