/**
 * H1 Repair Panel (editor sidebar)
 *
 * Alerts when the current post has no H1 and offers a source-level repair
 * (Elementor widget / Gutenberg block / classic content) scoped to THIS post
 * only. Preview is a dry run; Apply commits and the server keeps a restorable
 * backup. No hidden-H1 injection.
 *
 * Uses window.wp.* directly to match sibling panels.
 */

const H1RepairPanel = ({ postId }) => {
  const { createElement: h, useState, useEffect, useCallback } = window.wp.element;
  const { __ = (t) => t } = window.wp?.i18n || {};
  const { Button, Notice, Spinner } = window.wp.components;
  const apiFetch = window.wp.apiFetch;

  const [status, setStatus] = useState('idle');
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);
  const [preview, setPreview] = useState(null);
  const [working, setWorking] = useState(false);
  const [restoreMsg, setRestoreMsg] = useState(null);
  // Two-step restore: arming reveals explicit Confirm/Cancel buttons; the
  // entry button never commits directly. After a successful restore the
  // editor content is stale, so all other actions lock until reload.
  const [restoreArmed, setRestoreArmed] = useState(false);
  const [restoreCompleted, setRestoreCompleted] = useState(false);

  const refresh = useCallback(async () => {
    if (!postId || !apiFetch) return;
    setStatus('loading');
    setError(null);
    setPreview(null);
    try {
      const res = await apiFetch({ path: `/prorank-seo/v1/h1/post/${postId}`, method: 'GET' });
      setData(res);
      setStatus('ready');
    } catch (err) {
      setError(err?.message || __('Failed to check this post.', 'prorank-seo'));
      setStatus('error');
    }
  }, [postId, apiFetch]);

  useEffect(() => {
    refresh();
  }, [refresh]);

  const repair = useCallback(
    async (dryRun) => {
      if (!postId || !apiFetch) return;
      setWorking(true);
      setError(null);
      try {
        const res = await apiFetch({
          path: `/prorank-seo/v1/h1/repair/${postId}`,
          method: 'POST',
          data: { dry_run: dryRun },
        });
        if (dryRun) {
          setPreview(res);
        } else {
          setPreview(null);
          await refresh();
        }
      } catch (err) {
        setError(err?.message || __('Repair request failed.', 'prorank-seo'));
      } finally {
        setWorking(false);
      }
    },
    [postId, apiFetch, refresh]
  );

  const restore = useCallback(
    async (dryRun) => {
      if (!postId || !apiFetch) return;
      setWorking(true);
      setError(null);
      setRestoreMsg(null);
      try {
        const res = await apiFetch({
          path: `/prorank-seo/v1/h1/restore/${postId}`,
          method: 'POST',
          data: { dry_run: dryRun },
        });
        if (dryRun) {
          setRestoreArmed(true);
          setRestoreMsg(
            __('Ready to restore. Confirming reverts the post content to the pre-repair backup.', 'prorank-seo')
          );
        } else {
          setRestoreArmed(false);
          setRestoreMsg(null);
          setRestoreCompleted(true);
          await refresh();
        }
        return res;
      } catch (err) {
        setError(err?.message || __('Restore request failed.', 'prorank-seo'));
        return null;
      } finally {
        setWorking(false);
      }
    },
    [postId, apiFetch, refresh]
  );

  const cancelRestore = () => {
    setRestoreArmed(false);
    setRestoreMsg(null);
  };

  const renderRestore = () => {
    if (restoreCompleted) {
      return h(
        'div',
        { className: 'prorank-h1-restore', key: 'restore', style: { marginTop: '12px' } },
        h(
          Notice,
          { status: 'warning', isDismissible: false },
          h('strong', null, __('Editor content is out of date.', 'prorank-seo')),
          h(
            'p',
            null,
            __(
              'The post was restored from the pre-repair backup, but this editor still shows the old content. Reload the editor before making changes — saving now would overwrite the restore.',
              'prorank-seo'
            )
          )
        )
      );
    }

    if (!data?.has_backup) return null;
    return h(
      'div',
      { className: 'prorank-h1-restore', key: 'restore', style: { marginTop: '12px', borderTop: '1px solid #e0e0e0', paddingTop: '8px' } },
      h('p', { style: { fontSize: '12px', margin: '0 0 6px' } }, __('A pre-repair backup is available for this post.', 'prorank-seo')),
      !restoreArmed &&
        h(
          Button,
          { variant: 'secondary', isDestructive: true, onClick: () => restore(true), disabled: working },
          working ? __('Working…', 'prorank-seo') : __('Restore backup', 'prorank-seo')
        ),
      restoreArmed &&
        h(
          'div',
          { style: { display: 'flex', gap: '8px', flexWrap: 'wrap' } },
          h(
            Button,
            { variant: 'primary', isDestructive: true, onClick: () => restore(false), disabled: working },
            working ? __('Working…', 'prorank-seo') : __('Confirm restore', 'prorank-seo')
          ),
          h(
            Button,
            { variant: 'tertiary', onClick: cancelRestore, disabled: working },
            __('Cancel', 'prorank-seo')
          )
        ),
      restoreMsg ? h(Notice, { status: 'info', isDismissible: false }, restoreMsg) : null
    );
  };

  if (status === 'loading' || status === 'idle') {
    return h(
      'div',
      { className: 'prorank-panel-content' },
      h(Spinner, null),
      h('span', null, __('Checking for H1…', 'prorank-seo'))
    );
  }

  if (status === 'error') {
    return h(
      'div',
      { className: 'prorank-panel-content' },
      h(Notice, { status: 'error', isDismissible: false }, error),
      h(Button, { variant: 'secondary', onClick: refresh }, __('Retry', 'prorank-seo'))
    );
  }

  const diag = data?.diagnosis || {};
  const rendered = data?.rendered || {};
  const hasStoredH1 = !!diag.has_h1;
  const themeRendersH1 = !!rendered.has_rendered_h1;

  // The page is fine if stored content has an H1, or the theme renders one.
  if (hasStoredH1 || themeRendersH1) {
    return h(
      'div',
      { className: 'prorank-panel-content' },
      h(
        Notice,
        { status: 'success', isDismissible: false },
        hasStoredH1
          ? __('This post has an H1. No action needed.', 'prorank-seo')
          : __('The theme renders an H1 for this post. No action needed.', 'prorank-seo')
      ),
      h(
        Button,
        { variant: 'tertiary', onClick: refresh, disabled: restoreCompleted },
        __('Re-check', 'prorank-seo')
      ),
      renderRestore()
    );
  }

  const children = [
    h(
      Notice,
      { status: 'warning', isDismissible: false, key: 'alert' },
      h('strong', null, __('Missing H1', 'prorank-seo')),
      h(
        'p',
        null,
        __(
          'This post has no H1 heading. Search engines use the H1 as the primary on-page topic signal.',
          'prorank-seo'
        )
      )
    ),
  ];

  if (!diag.fixable) {
    children.push(
      h(
        Notice,
        { status: 'info', isDismissible: false, key: 'nofix' },
        __(
          'No safe automatic source-level fix is available for this post. Add an H1 heading manually in the editor.',
          'prorank-seo'
        )
      )
    );
  } else {
    children.push(
      h(
        'div',
        { className: 'prorank-h1-actions', key: 'actions', style: { display: 'flex', gap: '8px', flexWrap: 'wrap', marginTop: '8px' } },
        h(
          Button,
          { variant: 'secondary', onClick: () => repair(true), disabled: working || restoreCompleted },
          working ? __('Working…', 'prorank-seo') : __('Preview repair', 'prorank-seo')
        ),
        h(
          Button,
          {
            variant: 'primary',
            onClick: () => repair(false),
            disabled: working || restoreCompleted || !preview || !preview.mutated,
          },
          working ? __('Working…', 'prorank-seo') : __('Apply repair', 'prorank-seo')
        )
      )
    );
  }

  if (preview) {
    children.push(
      h(
        Notice,
        { status: preview.mutated ? 'info' : 'warning', isDismissible: false, key: 'preview' },
        preview.mutated
          ? __(
              'Preview: a source-level H1 fix is available. Nothing was written. Click "Apply repair" to commit (a restorable backup is kept).',
              'prorank-seo'
            )
          : `${__('No change available:', 'prorank-seo')} ${preview.reason || ''}`
      )
    );
  }

  if (error) {
    children.push(h(Notice, { status: 'error', isDismissible: false, key: 'err' }, error));
  }

  const restoreNode = renderRestore();
  if (restoreNode) {
    children.push(restoreNode);
  }

  return h('div', { className: 'prorank-panel-content' }, children);
};

export default H1RepairPanel;
