/**
 * Monaco JSON formatting (spec §03A; docs/architecture/08 → compact formatter).
 *
 * Two pieces, both backed by the portable core pretty-printer (`core/json-format`):
 *   - `configureJsonFormatter()` registers a document-formatting provider so
 *     "Format Document" (Shift+Alt+F) produces Vega's compact style.
 *   - `installFormatOnPaste(editor)` reindents the whole document after a paste,
 *     satisfying the spec's "pasting … triggers automatic reformatting".
 *
 * Both no-op when the document is not valid JSON, so a partial/in-progress paste
 * is never mangled (mirrors auto-save's "skip when unparseable" rule). Paste
 * handling is wired directly via `onDidPaste` rather than Monaco's `formatOnPaste`
 * option so it reformats the entire spec (not just the pasted range) and does not
 * depend on which registered formatter Monaco happens to pick.
 */

import * as monaco from 'monaco-editor/esm/vs/editor/edcore.main';
import { formatJson } from '@core/json-format';

let registered = false;

/** Register the compact JSON document formatter once. Idempotent. */
export function configureJsonFormatter(): void {
  if (registered) return;
  registered = true;
  monaco.languages.registerDocumentFormattingEditProvider('json', {
    provideDocumentFormattingEdits: (model, options) => {
      const current = model.getValue();
      const formatted = formatJson(current, { indent: options.tabSize });
      if (formatted === null || formatted === current) return [];
      return [{ range: model.getFullModelRange(), text: formatted }];
    },
  });
}

/**
 * Reformat the whole document after each paste. Returns a disposable; callers
 * dispose it when the editor unmounts.
 */
export function installFormatOnPaste(
  editor: monaco.editor.IStandaloneCodeEditor,
): monaco.IDisposable {
  return editor.onDidPaste(() => {
    const model = editor.getModel();
    if (!model) return;
    const current = model.getValue();
    const formatted = formatJson(current, { indent: model.getOptions().tabSize });
    if (formatted === null || formatted === current) return;
    editor.executeEdits('format-on-paste', [{ range: model.getFullModelRange(), text: formatted }]);
  });
}
