// #region DatasetDetailModel [C:3] [TYPE Model] [SEMANTICS dataset,detail,columns,dashboard,model]
// @ingroup Models
// @BRIEF Screen model for dataset detail page — loads dataset metadata, columns, SQL, and linked dashboards.
// @INVARIANT loadDatasetDetail() must only fire when datasetId and envId are both truthy.
// @STATE idle    — No context available (missing datasetId or envId).
// @STATE loading — API call in progress, skeleton visible.
// @STATE loaded  — Dataset details fetched, columns and dashboards rendered.
// @STATE error   — API call failed, error message displayed with retry.
// @ACTION loadDatasetDetail()  — Fetches dataset detail from API.
// @ACTION navigateToDashboard() — Navigates to linked dashboard detail.
// @ACTION goBack()              — Navigates back to dataset list.
// @ACTION getColumnTypeClass()  — Returns Tailwind class for column type chip.
// @RELATION DEPENDS_ON -> [ApiModule]
// @RELATION CALLS -> [CotLogger]

import { goto } from '$app/navigation';
import { ROUTES } from '$lib/routes';
import { api } from '$lib/api.js';
import { log } from '$lib/cot-logger';

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

interface DatasetColumn {
  name: string;
  type?: string;
  is_dttm?: boolean;
  is_active?: boolean;
  description?: string;
}

interface LinkedDashboard {
  id: number | string;
  title?: string;
  slug?: string;
}

interface DatasetDetail {
  table_name: string;
  schema?: string;
  database: string;
  column_count?: number;
  linked_dashboard_count?: number;
  is_sqllab_view?: boolean;
  created_on?: string;
  changed_on?: string;
  sql?: string;
  columns?: DatasetColumn[];
  linked_dashboards?: LinkedDashboard[];
}

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

export class DatasetDetailModel {
  // ── Atoms ─────────────────────────────────────────────────────
  dataset: DatasetDetail | null = $state(null);
  screenState: ScreenState = $state('idle');
  error: string | null = $state(null);

  // Set externally from page params
  datasetId: string = $state('');
  envId: string = $state('');

  // ── Derived ───────────────────────────────────────────────────
  isLoading = $derived(this.screenState === 'loading');
  columnCount = $derived(this.dataset?.column_count ?? 0);
  linkedDashCount = $derived(this.dataset?.linked_dashboard_count ?? 0);

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

  async loadDatasetDetail(): Promise<void> {
    if (!this.datasetId || !this.envId) {
      this.error = 'Missing context — dataset ID or environment ID not available.';
      this.screenState = 'error';
      return;
    }

    log('DatasetDetailModel', 'REASON', 'Loading dataset detail', {
      datasetId: this.datasetId,
      envId: this.envId,
    });

    this.screenState = 'loading';
    this.error = null;
    try {
      const response = await api.getDatasetDetail(this.envId, this.datasetId);
      this.dataset = response as DatasetDetail;
      this.screenState = 'loaded';
      log('DatasetDetailModel', 'REFLECT', 'Dataset detail loaded', {
        table: this.dataset.table_name,
        columns: this.dataset.column_count,
      });
    } catch (err: unknown) {
      this.error = err instanceof Error ? err.message : 'Failed to load dataset detail';
      this.screenState = 'error';
      log('DatasetDetailModel', 'EXPLORE', 'Failed to load dataset', { datasetId: this.datasetId }, String(this.error));
    }
  }

  navigateToDashboard(dashboard: LinkedDashboard): void {
    const ref = (dashboard as { slug?: string; id: string | number }).slug
      ?? (dashboard as { slug?: string; id: string | number }).id;
    if (!ref) return;
    goto(ROUTES.dashboards.detail(String(ref), this.envId));
  }

  goBack(): void {
    goto(ROUTES.datasets.list(this.envId));
  }

  // ── Static utilities (pure, no state access) ──────────────────

  static getColumnTypeClass(type: string | undefined): string {
    if (!type) return 'text-text-muted';
    const lt = type.toLowerCase();
    if (lt.includes('int') || lt.includes('float') || lt.includes('num')) {
      return 'text-primary bg-primary-light';
    } else if (lt.includes('date') || lt.includes('time')) {
      return 'text-success bg-success-light';
    } else if (lt.includes('str') || lt.includes('text') || lt.includes('char')) {
      return 'text-info bg-info-light';
    } else if (lt.includes('bool')) {
      return 'text-warning bg-warning-light';
    }
    return 'text-text-muted bg-surface-muted';
  }
}
// #endregion DatasetDetailModel
