/**
 * User font library (scope doc §4 → User font upload; spec §04 → Chart theme).
 *
 * The durable collection of uploaded font faces, referenced by `family` from a
 * config's font slots. Same two-layer shape as DatasetStore / CustomThemeStore:
 * low-level mutators (`add`/`addFonts`/`remove`) are the single place the `fonts`
 * array changes; a startup subscriber writes them through to IndexedDB.
 *
 * Persistence is NOT done here — `font-persistence.ts` observes this store and
 * writes through to the adapter — and neither is `FontFace` registration (a
 * browser side effect, owned by `services/fonts.ts` + `infrastructure/font-faces`),
 * so the store stays browser-free.
 */

import { create } from 'zustand';
import type { FontAsset } from '@core/font-asset';

export interface FontState {
  fonts: FontAsset[];

  /** Replace the library from storage. */
  hydrate: (fonts: FontAsset[]) => void;
  /** Add a fully-formed asset, assigning the next free id. Returns the stored record. */
  add: (font: FontAsset) => FontAsset;
  /** Batch add (import path): reassign ids from the store's authority and append. */
  addFonts: (incoming: FontAsset[]) => void;
  /** Remove a font by id. */
  remove: (id: number) => void;
  /** Reset to initial state (tests). */
  reset: () => void;
}

/** Next free numeric id — one past the max (same contract as `nextDatasetId`/`nextThemeId`). */
function nextFontId(fonts: ReadonlyArray<FontAsset>): number {
  return fonts.reduce((max, f) => Math.max(max, f.id), 0) + 1;
}

export const useFontStore = create<FontState>((set, get) => ({
  fonts: [],

  hydrate: (fonts) => set({ fonts }),

  add: (font) => {
    const withId = { ...font, id: nextFontId(get().fonts) };
    set((s) => ({ fonts: [...s.fonts, withId] }));
    return withId;
  },

  addFonts: (incoming) => {
    if (incoming.length === 0) return;
    set((s) => {
      let nextId = nextFontId(s.fonts);
      const withIds = incoming.map((f) => ({ ...f, id: nextId++ }));
      return { fonts: [...s.fonts, ...withIds] };
    });
  },

  remove: (id) => set((s) => ({ fonts: s.fonts.filter((f) => f.id !== id) })),

  reset: () => set({ fonts: [] }),
}));
