// rule-label — canonical display contract for deadline rules.
//
// t-paliad-258 / m/paliad#89 addendum. Previously each surface (deadline
// form, list rows, detail header, Schriftsätze tab, browse-a-proceeding)
// invented its own pattern: sometimes citation-only, sometimes name-only,
// sometimes "code — name". m flagged this on the first submissions in a
// proceeding sequence where the inconsistency was most visible.
//
// Canonical pattern: **Name primary, Citation muted secondary**.
//   Text: "Notice of Appeal · UPC.RoP.220.1"
//   HTML: <span class="rule-label-name">Notice of Appeal</span>
//         <span class="rule-label-sep"> · </span>
//         <span class="rule-label-cite">UPC.RoP.220.1</span>
//
// Custom rules (t-paliad-258 — free-text label entered by the lawyer):
//   formatCustomRuleLabel produces "<text>" with a "Custom" badge slot
//   so list/detail surfaces can render both shapes uniformly.

import { getLang, t } from "./i18n";

export interface RuleLike {
  name: string;
  name_en?: string | null;
  // The catalog carries multiple citation fields depending on which
  // surface populated it. Order of preference: legal_source > rule_code
  // > code. All three are accepted so callers don't have to normalise.
  rule_code?: string | null;
  code?: string | null;
  legal_source?: string | null;
}

// formatRuleLabel returns the canonical plain-text label.
// Falls back gracefully when either side is missing.
export function formatRuleLabel(r: RuleLike): string {
  const lang = getLang();
  const name = (lang === "en" && r.name_en) ? r.name_en : r.name;
  const cite = ruleCitation(r);
  if (name && cite) return `${name} · ${cite}`;
  return name || cite || "";
}

// formatRuleLabelHTML returns the canonical HTML form with muted-citation
// styling. The caller passes the HTML-escape helper so we don't pull a
// dependency on a specific esc() module — every surface already has one.
export function formatRuleLabelHTML(r: RuleLike, esc: (s: string) => string): string {
  const lang = getLang();
  const name = (lang === "en" && r.name_en) ? r.name_en : r.name;
  const cite = ruleCitation(r);
  if (name && cite) {
    return (
      `<span class="rule-label-name">${esc(name)}</span>` +
      `<span class="rule-label-sep"> · </span>` +
      `<span class="rule-label-cite">${esc(cite)}</span>`
    );
  }
  return esc(name || cite || "");
}

// ruleCitation returns the best-available citation string for a rule.
// Exported so callers that need the bare code (e.g. CalDAV exports,
// inline data attributes) can pull it without going through the label
// formatter.
export function ruleCitation(r: RuleLike): string {
  return r.legal_source || r.rule_code || r.code || "";
}

// formatCustomRuleLabelHTML — render a free-text custom rule label with
// a "Custom" badge slot. Used by surfaces that may display either a
// catalog rule (formatRuleLabelHTML) or a custom one. Returns "" when
// the text is empty so callers can fall through to "—".
export function formatCustomRuleLabelHTML(text: string | null | undefined, esc: (s: string) => string): string {
  const trimmed = (text ?? "").trim();
  if (!trimmed) return "";
  const badge = t("deadlines.field.rule.custom_badge") || "Custom";
  return (
    `<span class="rule-label-name">${esc(trimmed)}</span>` +
    `<span class="rule-label-badge rule-label-badge--custom">${esc(badge)}</span>`
  );
}

// formatCustomRuleLabel — plain-text equivalent of the above.
export function formatCustomRuleLabel(text: string | null | undefined): string {
  const trimmed = (text ?? "").trim();
  if (!trimmed) return "";
  const badge = t("deadlines.field.rule.custom_badge") || "Custom";
  return `${trimmed} · ${badge}`;
}
