export const SOURCE_EDITOR_FONT_SIZES = [10, 12, 14, 16, 18, 20, 24] as const;

export type SourceEditorSpellcheckMode = 'latex' | 'code';

const WORD_WRAP_STORAGE_KEY = 'learnitive:editor:word-wrap';
const LINE_NUMBERS_STORAGE_KEY = 'learnitive:editor:line-numbers';
const FONT_SIZE_STORAGE_KEY = 'learnitive:editor:font-size';
const SPELLCHECK_STORAGE_KEY = 'learnitive:editor:spellcheck';

const LEGACY_LATEX_WORD_WRAP_STORAGE_KEY = 'learnitive:latex-source:soft-wrap';
const LEGACY_LATEX_LINE_NUMBERS_STORAGE_KEY = 'learnitive:latex-source:line-numbers';
const LEGACY_LATEX_FONT_SIZE_STORAGE_KEY = 'learnitive:latex-source:font-size';
const LEGACY_LATEX_SPELLCHECK_STORAGE_KEY = 'learnitive:latex-source:spellcheck';

function readStorage(key: string): string | null {
  try {
    return window.localStorage.getItem(key);
  } catch {
    return null;
  }
}

function writeStorage(key: string, value: string): void {
  try {
    window.localStorage.setItem(key, value);
  } catch {
    // Browser privacy/storage restrictions must not make the editor unusable.
  }
}

function readBoolean(
  key: string,
  fallback: boolean,
  legacyKey?: string,
): boolean {
  const current = readStorage(key);
  if (current !== null) return current !== 'off';
  const legacy = legacyKey ? readStorage(legacyKey) : null;
  if (legacy !== null) return legacy !== 'off';
  return fallback;
}

function readFontSize(): number {
  const current = readStorage(FONT_SIZE_STORAGE_KEY);
  const legacy = current === null ? readStorage(LEGACY_LATEX_FONT_SIZE_STORAGE_KEY) : null;
  const parsed = Number(current ?? legacy);
  return Number.isFinite(parsed) && parsed >= 10 && parsed <= 24 ? parsed : 14;
}

export function readSourceEditorPreferences(): {
  wordWrap: boolean;
  lineNumbers: boolean;
  fontSize: number;
} {
  return {
    // Wrapping is a product-wide source-editor invariant. It must stay on by
    // default unless the user explicitly disables it.
    wordWrap: readBoolean(WORD_WRAP_STORAGE_KEY, true, LEGACY_LATEX_WORD_WRAP_STORAGE_KEY),
    lineNumbers: readBoolean(LINE_NUMBERS_STORAGE_KEY, true, LEGACY_LATEX_LINE_NUMBERS_STORAGE_KEY),
    fontSize: readFontSize(),
  };
}

export function persistSourceEditorWordWrap(enabled: boolean): void {
  writeStorage(WORD_WRAP_STORAGE_KEY, enabled ? 'on' : 'off');
}

export function persistSourceEditorLineNumbers(enabled: boolean): void {
  writeStorage(LINE_NUMBERS_STORAGE_KEY, enabled ? 'on' : 'off');
}

export function persistSourceEditorFontSize(size: number): void {
  const safe = Math.max(10, Math.min(24, size));
  writeStorage(FONT_SIZE_STORAGE_KEY, String(safe));
}

export function readSourceEditorSpellcheck(mode: SourceEditorSpellcheckMode): boolean {
  const key = `${SPELLCHECK_STORAGE_KEY}:${mode}`;
  return readBoolean(
    key,
    mode === 'latex',
    mode === 'latex' ? LEGACY_LATEX_SPELLCHECK_STORAGE_KEY : undefined,
  );
}

export function persistSourceEditorSpellcheck(
  mode: SourceEditorSpellcheckMode,
  enabled: boolean,
): void {
  writeStorage(`${SPELLCHECK_STORAGE_KEY}:${mode}`, enabled ? 'on' : 'off');
}
