// frontend/src/lib/models/MigrationSettingsModel.svelte.ts
// #region MigrationSettingsModel [C:4] [TYPE Model] [SEMANTICS settings,migration,sync,screen-model]
// @BRIEF State model for migration sync settings — cron schedule, sync-now, loading/saving/syncing state.
// @INVARIANT Settings are loaded before they can be saved or synced.
// @INVARIANT Sync-now updates settings (re-fetches cron) on completion.
// @ACTION loadSettings() — GET /migration/settings
// @ACTION saveSettings(data) — PUT /migration/settings
// @ACTION triggerSyncNow() — POST /migration/sync-now
// @RELATION DEPENDS_ON -> [EXT:frontend:api]
// @REJECTED Using inline $state + separate functions in MigrationSettings.svelte was rejected because it duplicated API logic, made testing harder, and violated the DRY model pattern established by MigrationModel and MappingsModel.
import { api } from "$lib/api.js";

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

interface SettingsPayload {
  cron: string;
}

interface SyncResult {
  synced_count: number;
  failed_count: number;
}

export class MigrationSettingsModel {
  // ── Atoms (reactive state) ──────────────────────────────────────

  /** Current cron expression. */
  cron: string = $state("0 2 * * *");

  /** True while saving settings. */
  saving: boolean = $state(false);

  /** True while syncing. */
  syncing: boolean = $state(false);

  /** Error message from last failed API call. */
  error: string = $state("");

  /** Success confirmation message. */
  success: string = $state("");

  /** Incremented to trigger parent-side refresh after sync. */
  refreshKey: number = $state(0);

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

  /**
   * Load migration settings from the API.
   * @POST cron is updated from API response on success, or error is set on failure.
   */
  async loadSettings(): Promise<void> {
    this.error = "";
    try {
      const settingsRes = await api.requestApi("/migration/settings");
      this.cron = settingsRes.cron;
    } catch (err: unknown) {
      this.error = err instanceof Error ? err.message : "Failed to load migration settings";
      console.error("[MigrationSettingsModel] Failed to load:", err);
    }
  }

  /**
   * Save migration settings (cron) to the API.
   * @POST On success: success message is set. On failure: error is set.
   */
  async saveSettings(data: SettingsPayload): Promise<void> {
    this.saving = true;
    this.error = "";
    this.success = "";
    try {
      await api.requestApi("/migration/settings", "PUT", data);
      this.success = "Settings saved successfully";
    } catch (err: unknown) {
      this.error = err instanceof Error ? err.message : "Failed to save migration settings";
    } finally {
      this.saving = false;
    }
  }

  /**
   * Trigger an immediate sync via the API.
   * @POST On success: refreshKey increments, settings reload, success message set.
   *       On failure: error is set.
   */
  async triggerSyncNow(): Promise<void> {
    this.syncing = true;
    this.error = "";
    this.success = "";
    try {
      const result: SyncResult = await api.postApi("/migration/sync-now", {});
      this.success = `Synced ${result.synced_count} environment(s)${
        result.failed_count > 0 ? `, ${result.failed_count} failed` : ""
      }`;
      this.refreshKey++;
      await this.loadSettings();
    } catch (err: unknown) {
      this.error = err instanceof Error ? err.message : "Sync failed";
      console.error("[MigrationSettingsModel] Sync failed:", err);
    } finally {
      this.syncing = false;
    }
  }
}
// #endregion MigrationSettingsModel
