import { IMAGES_PANEL_COLLAPSED_LS, SNIPPET_SIZE_MULTIPLIER_DEFAULT } from '../config/constants.js';
import { readLs } from '../core/storage.js';

export const userPrefsStore = {};

/** Cross-module mutable primitives (ES modules forbid reassigning imported `let` bindings). */
export const runtime = {
  userPrefsHydrated: false,
  userPrefsSaveTimer: null,
  themeMode: "light",
  shortcutBindingsOverrides:
    /** @type {Record<string, { ctrl: boolean; alt: boolean; shift: boolean; meta: boolean; code: string }>} */ ({}),
  shortcutRebindState: {
    active: false,
    mode: "capture",
    bindId: null,
    onKeyDoc: null,
    onKeyUpDoc: null,
    onMouseDoc: null,
  },
  uiToastHideTimer: /** @type {ReturnType<typeof setTimeout> | null} */ (null),
  zoomValueInputEditing: false,
  bdmPanInputEditing: false,
  recordInsertOverlayDepth: 0,
  headerAddOverlayDepth: 0,
  headerDeleteOverlayDepth: 0,
  recordDeleteOverlayDepth: 0,
  docTypeChangeOverlayDepth: 0,
  reorderOverlayDepth: 0,
  confirmActionResolver: null,
  typeToConfirmResolver: null,
  typeToConfirmExpectedValues: [],
  subProjectDeleteConfirmResolver: null,
  autocorrectChoiceResolver: null,
  lotAssignmentResolver: null,
  subProjectAssignSelection: null,
  workDetectionController: null,
  nextImageWork: null,
  /** Image id currently being painted during an image switch (before/during loadWork). */
  pendingDisplayImageId: /** @type {string|number|null} */ (null),
  userFocusPreference: "floating",
  activeEditInput: null,
};

export const state = {
  batch: null,
  docType: "",
  projectKinds: [],
  subProjects: [],
  batchDocTypeGroups: /** @type {object|null} */ (null),
  settingsOpen: false,
  images: [],
  imageIndex: -1,
  work: null,
  specFields: [],
  zoom: 100,
  panX: 0,
  panY: 0,
  formWidthPx: null,
  panDrag: null,
  selectedFieldsKind: "Census",
  fieldSearchQuery: "",
  fieldSelections: {},
  fieldOrders: {},
  fieldSelectionDefaults: {},
  fieldOrderDefaults: {},
  fieldSelectionsDirty: false,
  individualNumberAutoIncrement: false,
  individualNumberAutoIncrementDefault: false,
  preferredLastBatch: "",
  autoSkipValidatedRows: false,
  autoSkipAtFields: false,
  showShortcutsOnStartup: true,
  mergeHwrOrigColumn: false,
  showMergedHwrText: false,
  showLotAssignmentPrompt: true,
  /** When true, the left image list column is hidden (width 0). */
  imagesPanelCollapsed: false,
  bdmActsEnabled: false,
  imageViewerTab: "current",
  highlightFlashMode: false,
  /** When true, focus on an orig. field with coords zooms/pans to the rectangle. */
  rectAutoZoomEnabled: true,
  snippetEnabled: true,
  snippetSizeMultiplier: SNIPPET_SIZE_MULTIPLIER_DEFAULT,
  /** Root UI font scale (1 = 100%). */
  uiFontScale: 1,
  suggestRankingMode: "hybrid",
};

export const settingsUiState = {
  opening: false,
  lastOpenedAtMs: 0,
  projectKindsLoadedOnce: false,
  projectKindsInFlight: null,
  /** Chef de projet password configured in datafix_config.db3. */
  projectKindsLockConfigured: false,
  /** Kept for compatibility; unused with per-action password prompts. */
  projectKindsUnlocked: true,
  /** @type {"confirm"|"set"|"change"|null} */
  projectKindsPasswordMode: null,
  /** @type {((value: string | null) => void) | null} */
  projectKindsPasswordResolver: null,
  /**
   * Chef password remembered for this browser/app session only (lot assign).
   * Cleared on reload, password change, or a rejected password response.
   * @type {string | null}
   */
  sessionChefPassword: null,
};

export const subProjectEditorState = {
  editingId: /** @type {number | null} */ (null),
  /**
   * Chef password collected when opening Ajouter; reused for CI import / save
   * in this create session. Cleared on close. null means not collected yet.
   * @type {string | null}
   */
  pendingChefPassword: null,
};

export const subProfilePanelState = {
  subProject: /** @type {object | null} */ (null),
  /** When true, Seuil Rekey column is editable and search filters rows. */
  thresholdEditMode: false,
  fieldSearchQuery: "",
  /** Snapshot taken when entering edit mode; restored on cancel. */
  editSnapshot: /** @type {object | null} */ (null),
  /** After adding a DocType, refocus the add input in this category. */
  pendingDocTypeAddFocus: /** @type {"data" | "non_data" | null} */ (null),
};

export const desktopBridgeState = {
  status: "Chargement...",
};

export const statusDetailsState = {
  raw: "",
  open: false,
};

(function loadImagesPanelCollapsedPreference() {
  if (userPrefsStore.images_panel_collapsed === true) {
    state.imagesPanelCollapsed = true;
    return;
  }
  if (readLs(IMAGES_PANEL_COLLAPSED_LS) === "1") state.imagesPanelCollapsed = true;
})();


export const autosaveState = {
  timer: null,
  inFlight: false,
  needsFlush: false,
  pendingByEntity: new Map(),
};

export const historyState = {
  applying: false,
  undoStack: [],
  redoStack: [],
  pendingEdits: new Map(),
};

export const recordOpsState = {
  inFlight: false,
};

export const docTypeState = {
  inFlight: false,
};

export const suggestState = {
  timer: null,
  inFlightController: null,
  activeInput: null,
  items: [],
  highlightedIndex: -1,
  root: null,
};

export const highlightTimers = {
  hold: null,
  fade: null,
};
