/**
 * User settings state (spec §07, docs/architecture/01).
 *
 * Holds the **applied** preferences the app reads reactively — editor,
 * performance, and formatting. Following Astrolabe's distributed-settings model
 * (spec §07), each cluster is edited **in place**, next to what it affects (the
 * editor pane, the preview, the library), and every change applies **live**: a
 * setter mutates `saved` immediately and a startup subscriber writes it through
 * to localStorage (orchestration/settings). There is no draft/Apply/Cancel
 * stage — that's the explicit, commit-style model we replaced.
 *
 * UI theme and preview fit mode are not here: they live in the AppStore (the
 * header theme toggle and the preview Fit control), persisted onto the same
 * `UserSettings` record by their own slice subscribers. Settings controls that
 * change theme call `useAppStore.setTheme` directly, exactly like the toggle.
 */

import { create } from 'zustand';
import { defaultSettings, type UserSettings } from '@core/settings';

/** The clusters this store owns (theme + fit mode live in the AppStore). */
export type ManagedSettings = Pick<UserSettings, 'editor' | 'performance' | 'formatting'>;

/** Deep-copy the managed slice so callers never alias the stored record. */
function cloneManaged(s: ManagedSettings): ManagedSettings {
  return {
    editor: { ...s.editor },
    performance: { ...s.performance },
    formatting: { ...s.formatting },
  };
}

export interface UserSettingsState {
  /** The applied settings — the reactive source the editor/preview/library read. */
  saved: ManagedSettings;

  /** Replace `saved` from the persisted record at startup. */
  hydrate: (settings: UserSettings) => void;

  /** Live-patch a cluster (each produces a fresh `saved` → persistence fires). */
  setEditor: (patch: Partial<UserSettings['editor']>) => void;
  setPerformance: (patch: Partial<UserSettings['performance']>) => void;
  setFormatting: (patch: Partial<UserSettings['formatting']>) => void;

  /** Restore the editor cluster to its factory defaults (the editor popover's Reset). */
  resetEditor: () => void;
}

export const useUserSettingsStore = create<UserSettingsState>((set) => ({
  saved: cloneManaged(defaultSettings()),

  hydrate: (settings) => set({ saved: cloneManaged(settings) }),

  setEditor: (patch) =>
    set((s) => ({ saved: { ...s.saved, editor: { ...s.saved.editor, ...patch } } })),

  setPerformance: (patch) =>
    set((s) => ({ saved: { ...s.saved, performance: { ...s.saved.performance, ...patch } } })),

  setFormatting: (patch) =>
    set((s) => ({ saved: { ...s.saved, formatting: { ...s.saved.formatting, ...patch } } })),

  resetEditor: () =>
    set((s) => ({ saved: { ...s.saved, editor: { ...defaultSettings().editor } } })),
}));
