(function (wp) {
  const { __ } = wp.i18n;
  const { registerPlugin } = wp.plugins;
  const {
    PluginSidebar,
    PluginSidebarMoreMenuItem,
    PluginDocumentSettingPanel,
  } = wp.editPost || {};
  const { PanelBody, ToggleControl, TextControl, TextareaControl, CheckboxControl, Notice } = wp.components;
  const { useSelect, useDispatch } = wp.data;
  const { createElement: el, Fragment } = wp.element;

  const cfg = window.CALLIOPE_SP_EDITOR || {};
  const metaKeys = (cfg.metaKeys || {});
  const destinations = (cfg.destinations || []);
  const i18n = (cfg.i18n || {});
  const supportedPostTypes = Array.isArray(cfg.supportedPostTypes) ? cfg.supportedPostTypes : ['post', 'page'];

  function t(key, fallback) {
    return i18n[key] || fallback;
  }

  function normalizeHashtags(value) {
    const raw = String(value || '')
      .replace(/[\r\n\t,;]+/gu, ' ')
      .replace(/\s+/gu, ' ')
      .trim();

    if (!raw) return '';

    const parts = raw.split(' ');
    const normalized = [];
    const seen = new Set();

    parts.forEach((part) => {
      const tag = String(part || '')
        .replace(/^[#\s,;]+/gu, '')
        .replace(/[#\s,;]+$/gu, '')
        .replace(/[^\p{L}\p{M}\p{N}_]+/gu, '');

      if (!tag) return;

      const key = tag.toLocaleLowerCase();
      if (seen.has(key)) return;

      seen.add(key);
      normalized.push('#' + tag);
    });

    return normalized.join(' ');
  }

  function CalliopeSPPanel() {
    // Do NOT freeze selectors with [] deps.
    // In Gutenberg, current post type/meta can be undefined on first render;
    // if we don't subscribe, the panel may never appear.
    const postType = useSelect((select) => select('core/editor').getCurrentPostType());
    const isSupported = supportedPostTypes.includes(postType);

    const meta = useSelect((select) => select('core/editor').getEditedPostAttribute('meta') || {});
    const { editPost } = useDispatch('core/editor');

    const enabled = !!meta[metaKeys.enabled];
    const posted = !!meta[metaKeys.posted];
    const title = meta[metaKeys.title] || '';
    const text = meta[metaKeys.text] || '';
    const hashtags = meta[metaKeys.hashtags] || '';
    const normalizedHashtags = normalizeHashtags(hashtags);
    const dest = Array.isArray(meta[metaKeys.destinations]) ? meta[metaKeys.destinations] : [];
    const lastLogRaw = metaKeys.lastLog ? meta[metaKeys.lastLog] : '';

    let lastLog = null;
    if (typeof lastLogRaw === 'string' && lastLogRaw) {
      try {
        lastLog = JSON.parse(lastLogRaw);
      } catch (e) {
        lastLog = null;
      }
    }

    const lastSummary = lastLog && typeof lastLog.summary === 'string' ? lastLog.summary : '';
    const lastNoticeStatus = lastLog && typeof lastLog.notice_type === 'string'
      ? lastLog.notice_type
      : (posted ? 'success' : 'warning');

    function setMeta(key, value) {
      editPost({ meta: { ...meta, [key]: value } });
    }

    function toggleDest(key, checked) {
      const next = new Set(dest);
      if (checked) next.add(key);
      else next.delete(key);
      setMeta(metaKeys.destinations, Array.from(next));
    }

    if (!isSupported) return null;

    // Content UI reused in both the document panel and the plugin sidebar.
    const content = el(PanelBody, { initialOpen: true },
      posted ? el(Notice, { status: 'success', isDismissible: false },
        lastSummary || t('completedSuccess', __('Calliope Social Publisher has already published successfully to all selected destinations.', 'calliope-social-publisher'))
      ) : null,
      (!posted && lastLog && Number(lastLog.failed_count || 0) > 0) ? el(Notice, { status: lastNoticeStatus === 'error' ? 'error' : 'warning', isDismissible: false },
        lastSummary || t('partialFailure', __('Some destinations failed in the last automatic publishing attempt. Review the plugin logs or use the manual publisher if you want to retry.', 'calliope-social-publisher'))
      ) : null,
      el(ToggleControl, {
        label: t('enabled', __('Publish to social networks when this post is published', 'calliope-social-publisher')),
        checked: enabled,
        onChange: (v) => setMeta(metaKeys.enabled, !!v)
      }),
      el(TextControl, {
        label: t('title', __('Title (optional)', 'calliope-social-publisher')),
        value: title,
        onChange: (v) => setMeta(metaKeys.title, v)
      }),
      el(TextareaControl, {
        label: t('content', __('Content (optional)', 'calliope-social-publisher')),
        help: t('contentHelp', __('If left empty, the excerpt will be used.', 'calliope-social-publisher')),
        value: text,
        onChange: (v) => setMeta(metaKeys.text, v)
      }),
      el(TextControl, {
        label: t('hashtags', __('Hashtags', 'calliope-social-publisher')),
        help: normalizedHashtags ? t('normalizedTags', __('Normalized preview:', 'calliope-social-publisher')) + ' ' + normalizedHashtags : t('hashtagsHelp', __('You can separate hashtags with spaces, commas, semicolons, or line breaks. They will be normalized automatically.', 'calliope-social-publisher')),
        placeholder: '#seo #wordpress',
        value: hashtags,
        onChange: (v) => setMeta(metaKeys.hashtags, v),
        onBlur: () => {
          if (normalizedHashtags && normalizedHashtags !== hashtags) {
            setMeta(metaKeys.hashtags, normalizedHashtags);
          }
        }
      }),
      el('div', { style: { marginTop: '8px' } },
        el('strong', null, t('destinations', __('Destinations', 'calliope-social-publisher')))
      ),
      destinations.map((d) => el(CheckboxControl, {
        key: d.key,
        label: d.label,
        checked: dest.includes(d.key),
        onChange: (checked) => toggleDest(d.key, checked)
      }))
    );

    // If wp.editPost is not available (site editor / widgets), avoid JS errors.
    if (!PluginDocumentSettingPanel && !PluginSidebar) return null;

    return el(Fragment, null,
      // 1) Most visible: dedicated plugin sidebar + menu item.
      (PluginSidebar && PluginSidebarMoreMenuItem) ? el(Fragment, null,
        el(PluginSidebarMoreMenuItem, { target: 'calliope-social-publisher-sidebar' }, t('pluginName', __('Calliope Social Publisher', 'calliope-social-publisher'))),
        el(PluginSidebar, { name: 'calliope-social-publisher-sidebar', title: t('pluginName', __('Calliope Social Publisher', 'calliope-social-publisher')), icon: 'share' }, content)
      ) : null,

      // 2) Also keep it inside the Document settings sidebar for familiarity.
      PluginDocumentSettingPanel ? el(
        PluginDocumentSettingPanel,
        { name: 'calliope-social-publisher', title: t('pluginName', __('Calliope Social Publisher', 'calliope-social-publisher')), className: 'shp-gb-panel' },
        content
      ) : null
    );
  }

  registerPlugin('calliope-social-publisher-editor', { render: CalliopeSPPanel, icon: 'share' });
})(window.wp);
