// #region HealthCenterModel [C:5] [TYPE Model] [SEMANTICS health,center,matrix,filter,dashboard-list,model]
// @ingroup Models
// @BRIEF Screen model for Dashboard Health Center — matrix-driven filtering, card list, delete, env switching.
// @INVARIANT Changing environment reloads all data (matrix + cards).
// @INVARIANT Matrix click sets activeStatusFilter, re-derived filteredItems without reload.
// @INVARIANT Delete removes item locally only via SvelteSet tracking; full reload keeps state consistent.
// @STATE loading  — Initial load or environment switch in progress.
// @STATE loaded   — Health data displayed, matrix + cards rendered.
// @STATE error    — API call failed, error message visible.
// @ACTION loadData()              — Fetch health summary, environments, settings.
// @ACTION handleEnvChange(id)     — Switch environment and reload.
// @ACTION handleMatrixSelect(st)  — Set active status filter (cross-widget: matrix → card list).
// @ACTION handleDeleteReport(item) — Delete single health record.
// @ACTION clearFilter()           — Reset activeStatusFilter to ''.
// @RELATION DEPENDS_ON -> [ApiModule]
// @RELATION DEPENDS_ON -> [HealthStore]
// @RELATION CALLS -> [CotLogger]

import { SvelteSet } from 'svelte/reactivity';
import { getHealthSummary, getEnvironments, getConsolidatedSettings, requestApi } from '$lib/api.js';
import { healthStore } from '$lib/stores/health.svelte.js';
import { addToast } from '$lib/toasts.svelte.js';
import { log } from '$lib/cot-logger';

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

export interface HealthItem {
  record_id?: string;
  dashboard_id: string;
  dashboard_slug?: string;
  dashboard_title?: string;
  dashboard_name?: string;
  environment_id: string;
  status: string;
  last_check: string;
  task_id?: string;
  run_id?: string;
  policy_id?: string;
  summary?: string;
  execution_path?: string;
  issues_count?: number;
  timings?: Record<string, unknown>;
  chunk_count?: number;
}

interface HealthSummary {
  items: HealthItem[];
  pass_count: number;
  warn_count: number;
  fail_count: number;
  unknown_count: number;
}

type ScreenState = 'loading' | 'loaded' | 'error';

// ── Model ────────────────────────────────────────────────────────

export class HealthCenterModel {
  // ── Atoms ────────────────────────────────────────────────────
  /** Raw health data response (sum of all statuses). */
  healthData: HealthSummary = $state({ items: [], pass_count: 0, warn_count: 0, fail_count: 0, unknown_count: 0 });
  /** Available environments from API. */
  environments: Array<{ id: string; name?: string }> = $state([]);
  /** Currently selected environment ID (empty = all). */
  selectedEnvId: string = $state('');
  /** App timezone from consolidated settings. */
  appTimezone: string = $state('Europe/Moscow');
  /** UI screen state. */
  screenState: ScreenState = $state('loading');
  /** Human-readable error message. */
  error: string | null = $state(null);
  /** Set of record_ids currently being deleted (tracks in-flight deletes). */
  deletingReportIds = new SvelteSet<string>();
  /** Active status filter — set by matrix click, clears to show all. */
  activeStatusFilter: string = $state('');

  // ── Derived ─────────────────────────────────────────────────
  /** Cards filtered by matrix selection. @INVARIANT: no reload needed. */
  filteredItems: HealthItem[] = $derived(
    this.activeStatusFilter
      ? this.healthData.items.filter((item) => item.status === this.activeStatusFilter)
      : this.healthData.items,
  );

  // ── Actions ─────────────────────────────────────────────────

  /**
   * Fetch health summary, environments, and consolidated settings.
   * @POST healthData, environments, appTimezone populated on success.
   * @POST screenState → 'loaded' or 'error'.
   */
  async loadData(): Promise<void> {
    log('HealthCenterModel', 'REASON', 'Loading health center data', { env: this.selectedEnvId || 'all' });
    this.screenState = 'loading';
    this.error = null;
    try {
      const summaryPromise = this.selectedEnvId
        ? getHealthSummary(this.selectedEnvId)
        : healthStore.refresh();
      const [summary, envs, consolidated] = await Promise.all([
        summaryPromise,
        getEnvironments(),
        getConsolidatedSettings().catch(() => ({ app_timezone: 'Europe/Moscow' })),
      ]);
      this.healthData = summary as HealthSummary;
      this.environments = envs as Array<{ id: string; name?: string }>;
      this.appTimezone = (consolidated as { app_timezone?: string }).app_timezone || 'Europe/Moscow';

      if (!this.selectedEnvId && envs.length > 0) {
        // Try to restore from environment context store
        const { get } = await import('svelte/store');
        const envCtx = await import('$lib/stores/environmentContext.svelte.js');
        const state = get(envCtx.environmentContextStore);
        if (state.selectedEnvId && envs.some((e: { id: string }) => e.id === state.selectedEnvId)) {
          this.selectedEnvId = state.selectedEnvId;
        }
      }
      this.screenState = 'loaded';
      log('HealthCenterModel', 'REFLECT', 'Health data loaded', { items: this.healthData.items.length });
    } catch (e: unknown) {
      this.error = e instanceof Error ? e.message : String(e);
      this.screenState = 'error';
      log('HealthCenterModel', 'EXPLORE', 'Failed to load health data', { env: this.selectedEnvId }, String(this.error));
    }
  }

  /**
   * Switch environment and reload all data.
   * @POST selectedEnvId updated; loadData() called.
   */
  handleEnvChange(envId: string): void {
    this.selectedEnvId = envId;
    this.activeStatusFilter = '';
    this.error = null;
    void this.loadData();
  }

  /**
   * Set active status filter — triggered by matrix cell click.
   * @POST filteredItems re-derived. Empty string shows all.
   */
  handleMatrixSelect(status: string): void {
    this.activeStatusFilter = status;
  }

  /**
   * Delete a single health report record.
   * @SIDE_EFFECT DELETE API call; reloads data on success.
   */
  async handleDeleteReport(item: HealthItem): Promise<void> {
    if (!item?.record_id || this.deletingReportIds.has(item.record_id)) return;
    this.deletingReportIds.add(item.record_id);
    try {
      await requestApi(`/health/summary/${item.record_id}`, 'DELETE');
      // Reload to keep state consistent
      await this.loadData();
    } catch (e: unknown) {
      const msg = e instanceof Error ? e.message : 'Unknown';
      addToast(`Failed to delete: ${msg}`, 'error');
    } finally {
      this.deletingReportIds.delete(item.record_id);
    }
  }

  /** Reset active status filter to show all dashboards. */
  clearFilter(): void {
    this.activeStatusFilter = '';
  }
}
// #endregion HealthCenterModel
