// #region Dashboards.SelectionModel [C:3] [TYPE Model] [SEMANTICS dashboard,selection,checkbox,bulk-action]
// @ingroup Dashboards
// @BRIEF Selection state and checkbox logic for the dashboard hub grid. Owned by Dashboards.HubModel.
// @INVARIANT Selection never contains IDs not present in allDashboards (cleaned on load via parent).
// @STATE none       — No dashboards selected.
// @STATE partial    — Some dashboards selected.
// @STATE all        — All filtered dashboards selected.
// @ACTION updateSelectionState()  — Recomputes isAllSelected and isAllVisibleSelected.
// @ACTION replaceSelectedIds(set) — Replaces the entire selection set.
// @ACTION clearSelectedIds()      — Empties selection.
// @ACTION handleCheckboxChange(d, e) — Toggles one dashboard in selection.
// @ACTION handleSelectAll()       — Toggles select all filtered dashboards.
// @ACTION handleSelectVisible()   — Toggles select visible page dashboards.
// @RELATION CALLED_BY -> [Dashboards.HubModel]

import { SvelteSet } from "svelte/reactivity";

// ── Types ────────────────────────────────────────────────────────

interface DashboardRow {
  id: string; title: string; slug: string;
  changedOn: string | null; changedOnLabel: string;
  owners: string[]; actorLabel: string;
  git: { status: string; branch: string | null; hasRepo: boolean | null; hasChangesForCommit: boolean };
  lastTask: { status: string | null; validationStatus: string; id: string } | null;
  actions: string[];
}

// ═══ Model ═══════════════════════════════════════════════════════

export class DashboardsSelectionModel {
  // ── Selection state ───────────────────────────────────────────
  selectedIds: Set<string> = $state(new SvelteSet());
  isAllSelected: boolean = $state(false);
  isAllVisibleSelected: boolean = $state(false);

  // ═══ Selection methods ═════════════════════════════════════════

  updateSelectionState(filteredDashboards: DashboardRow[], dashboards: DashboardRow[]): void {
    this.isAllSelected = this.selectedIds.size === filteredDashboards.length && filteredDashboards.length > 0;
    this.isAllVisibleSelected = this.selectedIds.size === dashboards.length && dashboards.length > 0;
  }

  replaceSelectedIds(next: Set<string>): void { this.selectedIds = next; }
  clearSelectedIds(): void { this.replaceSelectedIds(new SvelteSet()); }

  handleCheckboxChange(dashboard: DashboardRow, event: Event): void {
    const next = new SvelteSet(this.selectedIds);
    (event.target as HTMLInputElement).checked ? next.add(dashboard.id) : next.delete(dashboard.id);
    this.replaceSelectedIds(next);
  }

  handleSelectAll(filteredDashboards: DashboardRow[]): void {
    if (this.isAllSelected) { this.clearSelectedIds(); return; }
    const next = new SvelteSet(this.selectedIds);
    filteredDashboards.forEach(d => next.add(d.id));
    this.replaceSelectedIds(next);
  }

  handleSelectVisible(dashboards: DashboardRow[]): void {
    const next = new SvelteSet(this.selectedIds);
    if (this.isAllVisibleSelected) { dashboards.forEach(d => next.delete(d.id)); }
    else { dashboards.forEach(d => next.add(d.id)); }
    this.replaceSelectedIds(next);
  }
}
// #endregion Dashboards.SelectionModel
