/**
 * LANE-UI — item chips. A chip is a color swatch + item name + a count, and it is the
 * only way items are ever shown in the HUD (inspector buffers, recipe I/O, fax wants).
 *
 * Colors and names come from GameData.items — nothing here hard-codes an item id, so
 * new items from LANE-DATA light up with zero code (CONTRACTS "IDs are data-driven").
 */
import type { ItemDef } from '../contracts';
import { attrs, el, text } from './dom';

export type ChipState = 'plain' | 'short' | 'met';

export interface ChipSpec {
  item: string;
  /** Right-hand count text, e.g. "3" or "3/40". */
  count: string;
  state?: ChipState;
}

export interface ChipRow {
  el: HTMLElement;
  update(specs: ChipSpec[]): void;
}

/** Items the codex hasn't taught us about yet still get a chip, just a drab one. */
const UNKNOWN: Pick<ItemDef, 'name' | 'color'> = { name: '???', color: '#6a8a6a' };

export function createChipRow(items: Map<string, ItemDef>): ChipRow {
  const root = el('div', 'fk-chips');
  const live = new Map<string, { chip: HTMLElement; sw: HTMLElement; n: HTMLElement }>();

  return {
    el: root,
    update(specs) {
      const seen = new Set<string>();

      for (const spec of specs) {
        seen.add(spec.item);
        let entry = live.get(spec.item);

        if (!entry) {
          const def = items.get(spec.item) ?? UNKNOWN;
          const sw = el('span', 'fk-chip-sw');
          sw.style.background = def.color;
          const n = el('span', 'fk-chip-n');
          const chip = el('span', 'fk-chip', [sw, def.name, n]);
          attrs(chip, { title: spec.item });
          entry = { chip, sw, n };
          live.set(spec.item, entry);
          root.appendChild(chip);
        }

        text(entry.n, spec.count);
        // One class per state; className assignment is cheap and avoids stale flags.
        const state = spec.state ?? 'plain';
        const want = state === 'plain' ? 'fk-chip' : `fk-chip is-${state}`;
        if (entry.chip.className !== want) entry.chip.className = want;
      }

      for (const [id, entry] of live) {
        if (seen.has(id)) continue;
        entry.chip.remove();
        live.delete(id);
      }

      // Keep DOM order matching spec order (chips are few; this is cheap).
      for (const spec of specs) {
        const entry = live.get(spec.item);
        if (entry) root.appendChild(entry.chip);
      }
    },
  };
}
