/**
 * Editor.js integration — lifecycle-managed page editor module.
 */
import EditorJS from '../../vendor/editorjs/editorjs.mjs';
import { postForm } from '../core/app-http.js';
import { warnOnce, resolveHost } from '../core/app-dom.js';

const parseData = (value) => {
  if (!value) {
    return { blocks: [] };
  }
  try {
    const parsed = JSON.parse(value);
    if (parsed && typeof parsed === 'object') {
      if (!Array.isArray(parsed.blocks)) {
        parsed.blocks = [];
      }
      return parsed;
    }
  } catch {
    // ignore invalid JSON
  }
  return { blocks: [] };
};

const resolveTools = (form) => {
  const HeaderTool = window.Header || window.EditorJSHeader || null;
  const ListTool = window.EditorjsList || window.List || null;
  const ChecklistTool = window.Checklist || window.EditorJSChecklist || null;
  const TableTool = window.Table || window.EditorJSTable || null;
  const ColumnsTool = window.editorjsColumns || window.Columns || null;
  const MarkerTool = window.Marker || null;

  const tools = {};
  if (HeaderTool) {
    tools.header = {
      class: HeaderTool,
      inlineToolbar: true,
      config: {
        placeholder: form.dataset.headerPlaceholder || 'Heading',
        levels: [1, 2, 3, 4],
        defaultLevel: 1,
      },
    };
  }
  if (ListTool) {
    tools.list = {
      class: ListTool,
      inlineToolbar: true,
      config: {
        defaultStyle: 'unordered',
      },
    };
  }
  if (ChecklistTool) {
    tools.checklist = {
      class: ChecklistTool,
      inlineToolbar: true,
    };
  }
  if (TableTool) {
    tools.table = {
      class: TableTool,
      inlineToolbar: true,
      config: {
        rows: 2,
        cols: 2,
      },
    };
  }
  if (ColumnsTool) {
    const innerTools = { ...tools };
    tools.columns = {
      class: ColumnsTool,
      config: {
        EditorJsLibrary: EditorJS,
        tools: innerTools,
      },
    };
  }
  if (MarkerTool) {
    tools.marker = {
      class: MarkerTool,
      shortcut: 'CMD+SHIFT+M',
    };
  }

  return {
    tools,
    inlineTools: MarkerTool ? ['marker', 'bold', 'italic', 'link'] : ['bold', 'italic', 'link'],
  };
};

export function initPageEditor(root = document, config = {}) {
  const host = resolveHost(root);
  const formSelector = String(config.selector || '[data-page-editor]').trim() || '[data-page-editor]';
  const form = host.matches?.(formSelector) ? host : host.querySelector(formSelector);
  if (!(form instanceof HTMLFormElement)) {
    return { destroy: () => {} };
  }
  if (form.dataset.pageEditorBound === '1' && form._pageEditorApi) {
    return form._pageEditorApi;
  }

  const holderSelector = String(config.holderSelector || '[data-editor-holder]').trim() || '[data-editor-holder]';
  const contentFieldSelector = String(config.contentFieldSelector || '#page-content').trim() || '#page-content';
  const controlsRootSelector = String(config.controlsRootSelector || '').trim();
  const toggleSelector = String(config.toggleSelector || '[data-editor-toggle]').trim() || '[data-editor-toggle]';
  const saveSelector = String(config.saveSelector || '[data-editor-save]').trim() || '[data-editor-save]';

  const holder = form.querySelector(holderSelector);
  if (!(holder instanceof HTMLElement)) {
    warnOnce('UI_EL_MISSING', 'Missing editor holder', { module: 'page-editor' });
    return { destroy: () => {} };
  }

  const contentField = form.querySelector(contentFieldSelector);
  if (!(contentField instanceof HTMLTextAreaElement)) {
    warnOnce('UI_EL_MISSING', `Missing page editor content field: ${contentFieldSelector}`, { module: 'page-editor' });
    return { destroy: () => {} };
  }

  const controlsRoot = controlsRootSelector !== ''
    ? document.querySelector(controlsRootSelector)
    : document;
  const controlsHost = controlsRoot && typeof controlsRoot.querySelector === 'function'
    ? controlsRoot
    : document;
  const toggleButton = controlsHost.querySelector(toggleSelector);
  const saveButton = controlsHost.querySelector(saveSelector);

  const canEdit = form.dataset.canEdit === '1';
  let mode = form.dataset.editMode === 'edit' && canEdit ? 'edit' : 'view';
  form.dataset.editMode = mode;
  form.dataset.pageEditorBound = '1';

  const setToggleLabel = (nextMode) => {
    if (!(toggleButton instanceof HTMLElement)) {
      return;
    }
    const viewLabel = toggleButton.dataset.viewLabel || '';
    const editLabel = toggleButton.dataset.editLabel || '';
    const text = nextMode === 'edit' ? viewLabel : editLabel;
    const icon = toggleButton.querySelector('[data-editor-icon]');

    if (icon instanceof HTMLElement) {
      icon.className = nextMode === 'edit' ? 'bi bi-eye-fill' : 'bi bi-pencil-square';
    }
    toggleButton.setAttribute('aria-label', text);
    toggleButton.dataset.tooltip = text;
  };

  setToggleLabel(mode);
  if (saveButton instanceof HTMLButtonElement) {
    saveButton.disabled = mode !== 'edit';
  }

  const toolConfig = resolveTools(form);
  const editor = new EditorJS({
    holder,
    data: parseData(contentField.value),
    readOnly: mode !== 'edit',
    autofocus: mode === 'edit',
    placeholder: form.dataset.placeholder || undefined,
    tools: toolConfig.tools,
    inlineToolbar: toolConfig.inlineTools,
  });

  const toggleMode = async (nextMode) => {
    if (!canEdit || mode === nextMode) {
      return;
    }
    mode = nextMode;
    form.dataset.editMode = mode;
    setToggleLabel(mode);
    if (editor.readOnly && typeof editor.readOnly.toggle === 'function') {
      await editor.readOnly.toggle(mode !== 'edit');
    }
    if (saveButton instanceof HTMLButtonElement) {
      saveButton.disabled = mode !== 'edit';
    }
  };

  const onToggleClick = () => {
    void toggleMode(mode === 'edit' ? 'view' : 'edit');
  };

  const onSubmit = async (event) => {
    if (form.dataset.submitting === '1') {
      return;
    }
    event.preventDefault();
    const output = await editor.save();
    contentField.value = JSON.stringify(output);
    form.dataset.submitting = '1';

    try {
      const data = await postForm(form.action || window.location.pathname, new FormData(form));
      if (data && typeof data === 'object' && typeof data.redirect === 'string' && data.redirect.trim() !== '') {
        window.location.href = data.redirect;
        return;
      }
      window.location.reload();
    } catch {
      form.submit();
    }
  };

  if (toggleButton instanceof HTMLElement && canEdit) {
    toggleButton.addEventListener('click', onToggleClick);
  }
  if (canEdit) {
    form.addEventListener('submit', onSubmit);
  }

  let destroyed = false;
  const destroy = () => {
    if (destroyed) {
      return;
    }
    destroyed = true;
    if (toggleButton instanceof HTMLElement && canEdit) {
      toggleButton.removeEventListener('click', onToggleClick);
    }
    if (canEdit) {
      form.removeEventListener('submit', onSubmit);
    }
    if (typeof editor.destroy === 'function') {
      editor.destroy();
    }
    delete form.dataset.pageEditorBound;
    delete form._pageEditorApi;
  };

  const api = { destroy };
  form._pageEditorApi = api;
  return api;
}
