import { Config } from "@systems/config"; import { submitScore, detectSlot, normalizeSlot } from "@systems/scores"; import { getEffectiveCharacter } from "@systems/borrow"; import { format } from "@format"; import { getEmoji } from "@systems/emojis"; // ─── Types ──────────────────────────────────────────────────────────────────── export interface ScoreSubmitInput { userKey: string; pts: number; slot?: number | string | null; // number = already resolved, string = needs normalizing, null/undefined = auto-detect k?: number; d?: number; atk?: number; def?: number; heal?: number; submittedByOfficer?: boolean; } export type ScoreSubmitResult = | { ok: true; message: string } | { ok: false; message: string }; // ─── Core ───────────────────────────────────────────────────────────────────── export namespace score { /** * Resolve, validate and persist a score submission for a given userKey. * Used by both the slash command handler and the modal submit handler. */ export async function submitForUser(input: ScoreSubmitInput): Promise { const { userKey, pts, k, d, atk, def, heal, submittedByOfficer = false } = input; const { char, borrowedFrom } = getEffectiveCharacter(userKey); if (!char) { return { ok: false, message: "❌ No active character found. Use `/tg char set-active` first." }; } // Resolve slot let slot: number | null = null; if (typeof input.slot === "number") { slot = input.slot; } else if (typeof input.slot === "string") { slot = normalizeSlot(input.slot); if (slot === null) { return { ok: false, message: `❌ Could not parse slot "${input.slot}".` }; } } else { slot = detectSlot() ?? Config.get({ section: "poll", key: "slots" }).find((s) => s.active)?.tgHour ?? 20; } await submitScore({ userKey: borrowedFrom ?? userKey, playedBy: borrowedFrom ? userKey : undefined, characterName: char.name, cls: char.class, nation: char.nation, pts, k, d, slot, atk, def, heal, submittedByOfficer, }); const scoreEmoji = getEmoji("score") || "📊"; const kdEmoji = getEmoji("kd") || "⚔️"; const kdNote = k !== undefined && d !== undefined ? `\n${kdEmoji} ${k}/${d}` : ""; const statsNote = [ atk !== undefined ? `ATK: ${atk}` : null, def !== undefined ? `DEF: ${def}` : null, heal !== undefined ? `HEAL: ${heal}` : null, ].filter(Boolean).join(" · "); const charDisplay = format.char(char); const borrowNote = borrowedFrom ? ` *(borrowed from ${borrowedFrom})*` : ""; const line = format.scoreSubmitLine({ slot, char, pts, k, d, atk, def, heal, }); return { ok: true, message: `✅ ${line}${borrowNote}`, }; } }