/**
 * Schemafy Gutenberg Sidebar v1.7.0
 * Tabs: SEO | Social | Schema
 * New: dirty badge, Google test link, JSON viewer, auto-detect, export
 */
(function(wp) {
    'use strict';

    if (!wp || !wp.plugins || !wp.editPost || !wp.element || !wp.coreData) return;

    const { registerPlugin }                           = wp.plugins;
    const { PluginSidebar, PluginSidebarMoreMenuItem } = wp.editPost;
    const { TextControl, TextareaControl,
            Button, Spinner, Icon, SelectControl }     = wp.components;
    const { useState, useEffect, useCallback,
            useMemo, useRef, Fragment }                = wp.element;
    const { useSelect }                                = wp.data;
    const { useEntityProp }                            = wp.coreData;
    const apiFetch                                     = wp.apiFetch;

    const cfg        = window.schemafyGutenberg || {};
    const siteUrl    = cfg.siteUrl   || '';
    const siteName   = cfg.siteName  || '';
    const adminUrl   = cfg.adminUrl  || '/wp-admin/admin.php?page=schemafy-custom-schema';
    const schemaTypes = cfg.schemaTypes || [];

    // ─── Helpers ───────────────────────────────────────────────────────────────

    const usePostUrl = () => useSelect(sel => {
        const { getPermalink, getCurrentPostId } = sel('core/editor');
        const id = getCurrentPostId();
        return getPermalink() || (id ? cfg.postUrl || `${siteUrl}/?p=${id}` : '');
    }, []);

    const usePostId = () => useSelect(sel => sel('core/editor').getCurrentPostId(), []);

    const parseUrl = raw => {
        try {
            const p = new URL(raw || siteUrl || 'https://example.com');
            const segs = p.pathname.split('/').filter(Boolean);
            return { host: p.hostname, crumb: segs.length ? p.hostname + ' › ' + segs.join(' › ') : p.hostname };
        } catch { return { host: siteUrl || 'example.com', crumb: siteUrl || 'example.com' }; }
    };

    const openAdmin = (tab, url) => {
        const p = new URLSearchParams({ tab });
        if (url) p.set('url', url);
        window.open(`${adminUrl}&${p}`, '_blank');
    };

    const schemaInfo = type => schemaTypes.find(t => t.value === type) || { icon: '📄', label: type };

    // Open WP media library picker
    const openMediaPicker = (onSelect) => {
        if (!wp.media) { const url = prompt('Paste image URL:'); if (url) onSelect(url); return; }
        const frame = wp.media({ title: 'Select Image', button: { text: 'Use this image' }, multiple: false, library: { type: 'image' } });
        frame.on('select', () => { const att = frame.state().get('selection').first().toJSON(); onSelect(att.url); });
        frame.open();
    };

    // Trigger a JSON file download in the browser
    const downloadJson = (data, filename) => {
        const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
        const url  = URL.createObjectURL(blob);
        const a    = document.createElement('a');
        a.href = url; a.download = filename; a.click();
        URL.revokeObjectURL(url);
    };

    // ─── CharPill ──────────────────────────────────────────────────────────────

    const CharPill = ({ count, min, max }) => {
        const ok   = count >= min && count <= max;
        const over = count > max;
        const col  = count === 0 ? '#9ca3af' : ok ? '#16a34a' : over ? '#dc2626' : '#d97706';
        const txt  = count === 0 ? `0/${max}` : ok ? `${count}/${max} ✓` : over ? `${count}/${max} −${count-max}` : `${count}/${max} +${min-count}`;
        return wp.element.createElement('div', { className: 'sch-charpill' },
            wp.element.createElement('div', { className: 'sch-charpill__bar' },
                wp.element.createElement('div', { className: 'sch-charpill__fill', style: { width: `${Math.min((count/max)*100,100)}%`, background: col } })
            ),
            wp.element.createElement('span', { className: 'sch-charpill__label', style: { color: col, background: `${col}18` } }, txt)
        );
    };

    // ─── KwBadge — keyword found indicator ────────────────────────────────────

    const KwBadge = ({ label, found }) =>
        wp.element.createElement('span', {
            className: `sch-kw-badge${found ? ' sch-kw-badge--ok' : ' sch-kw-badge--miss'}`
        }, found ? `✓ ${label}` : `✗ ${label}`);

    // ─── GooglePreview ─────────────────────────────────────────────────────────

    const GooglePreview = ({ title, description, url, device }) => {
        const { host, crumb } = useMemo(() => parseUrl(url), [url]);
        const [favOk, setFavOk] = useState(false);
        const favSrc = url ? `https://www.google.com/s2/favicons?sz=32&domain_url=${encodeURIComponent(url)}` : '';
        const isMobile = device === 'mobile';

        return wp.element.createElement('div', { className: `sch-preview${isMobile ? ' sch-preview--mobile' : ''}` },
            wp.element.createElement('div', { className: 'sch-preview__site-row' },
                wp.element.createElement('div', { className: 'sch-preview__fav' },
                    favSrc && wp.element.createElement('img', {
                        src: favSrc, width: isMobile ? 14 : 16, height: isMobile ? 14 : 16,
                        onLoad: () => setFavOk(true), onError: () => setFavOk(false),
                        style: { display: favOk ? 'block' : 'none' }
                    }),
                    !favOk && wp.element.createElement(Icon, { icon: 'admin-site-alt3', style: { width: isMobile ? '12px' : '14px', height: isMobile ? '12px' : '14px', color: '#5f6368' } })
                ),
                wp.element.createElement('div', null,
                    !isMobile && wp.element.createElement('div', { className: 'sch-preview__site-name' }, siteName || host),
                    wp.element.createElement('div', { className: isMobile ? 'sch-preview__domain' : 'sch-preview__crumb' }, isMobile ? host : crumb)
                )
            ),
            wp.element.createElement('div', { className: 'sch-preview__title' }, title || 'Your page title will appear here'),
            wp.element.createElement('div', { className: 'sch-preview__desc' }, description || 'Your meta description will appear here. Write a compelling description to improve click-through rates.')
        );
    };

    // ─── FbPreview ─────────────────────────────────────────────────────────────

    const FbPreview = ({ title, description, image, url }) => {
        const { host } = useMemo(() => parseUrl(url), [url]);
        return wp.element.createElement('div', { className: 'sch-fb-preview' },
            wp.element.createElement('div', { className: 'sch-fb-preview__img' },
                image
                    ? wp.element.createElement('img', { src: image, alt: '' })
                    : wp.element.createElement('div', { className: 'sch-fb-preview__img-placeholder' },
                        wp.element.createElement(Icon, { icon: 'format-image', style: { width: '24px', height: '24px', color: '#9ca3af' } })
                      )
            ),
            wp.element.createElement('div', { className: 'sch-fb-preview__body' },
                wp.element.createElement('div', { className: 'sch-fb-preview__domain' }, host.toUpperCase()),
                wp.element.createElement('div', { className: 'sch-fb-preview__title' }, title || 'Page title'),
                wp.element.createElement('div', { className: 'sch-fb-preview__desc' }, description || 'Description')
            )
        );
    };

    // ─── TwitterPreview ────────────────────────────────────────────────────────

    const TwitterPreview = ({ title, description, image, url, cardType }) => {
        const { host } = useMemo(() => parseUrl(url), [url]);
        const isSummary = cardType === 'summary';

        if (isSummary) {
            return wp.element.createElement('div', { className: 'sch-tw-preview sch-tw-preview--summary' },
                wp.element.createElement('div', { className: 'sch-tw-preview__thumb' },
                    image
                        ? wp.element.createElement('img', { src: image, alt: '' })
                        : wp.element.createElement(Icon, { icon: 'format-image', style: { width: '20px', height: '20px', color: '#9ca3af' } })
                ),
                wp.element.createElement('div', { className: 'sch-tw-preview__body' },
                    wp.element.createElement('div', { className: 'sch-tw-preview__title' }, title || 'Page title'),
                    wp.element.createElement('div', { className: 'sch-tw-preview__desc' }, description || 'Description'),
                    wp.element.createElement('div', { className: 'sch-tw-preview__domain' }, host)
                )
            );
        }

        return wp.element.createElement('div', { className: 'sch-tw-preview' },
            wp.element.createElement('div', { className: 'sch-tw-preview__img' },
                image
                    ? wp.element.createElement('img', { src: image, alt: '' })
                    : wp.element.createElement('div', { className: 'sch-tw-preview__img-placeholder' },
                        wp.element.createElement(Icon, { icon: 'format-image', style: { width: '24px', height: '24px', color: '#9ca3af' } })
                      )
            ),
            wp.element.createElement('div', { className: 'sch-tw-preview__caption' },
                wp.element.createElement('div', { className: 'sch-tw-preview__title' }, title || 'Page title'),
                wp.element.createElement('div', { className: 'sch-tw-preview__desc' }, description || 'Description'),
                wp.element.createElement('div', { className: 'sch-tw-preview__domain' }, host)
            )
        );
    };

    // ─── ImageField ────────────────────────────────────────────────────────────

    const ImageField = ({ value, onChange, label }) =>
        wp.element.createElement('div', { className: 'sch-img-field' },
            wp.element.createElement('label', { className: 'sch-label' }, label),
            value
                ? wp.element.createElement(Fragment, null,
                    wp.element.createElement('div', { className: 'sch-img-field__preview' },
                        wp.element.createElement('img', { src: value, alt: '' }),
                        wp.element.createElement('button', {
                            className: 'sch-img-field__remove',
                            onClick: () => onChange(''),
                            title: 'Remove image'
                        }, wp.element.createElement(Icon, { icon: 'no-alt', style: { width: '14px', height: '14px' } }))
                    )
                  )
                : wp.element.createElement('button', {
                    className: 'sch-img-field__pick',
                    onClick: () => openMediaPicker(onChange)
                  },
                    wp.element.createElement(Icon, { icon: 'format-image', style: { width: '16px', height: '16px' } }),
                    'Select image'
                  )
        );

    // ─── JsonViewer — collapsible JSON-LD preview ──────────────────────────────

    const JsonViewer = ({ jsonString }) => {
        let pretty;
        try { pretty = JSON.stringify(JSON.parse(jsonString), null, 2); }
        catch { pretty = jsonString || '{}'; }

        return wp.element.createElement('div', { className: 'sch-json-viewer' },
            wp.element.createElement('pre', { className: 'sch-json-viewer__pre' }, pretty)
        );
    };

    // ─── AutoDetect — schema type recommendations ──────────────────────────────

    const AutoDetect = ({ postId, postUrl }) => {
        const [state,    setState]    = useState('idle'); // idle | loading | done
        const [recs,     setRecs]     = useState([]);
        const [wordCount, setWC]      = useState(null);

        const detect = useCallback(async () => {
            if (!postId) return;
            setState('loading');
            try {
                const res = await apiFetch({ path: `schemafy/v1/auto-detect/${postId}` });
                setRecs(res.recommendations || []);
                setWC(res.word_count ?? null);
                setState('done');
            } catch(e) {
                setRecs([]); setState('done');
            }
        }, [postId]);

        const reset = () => { setState('idle'); setRecs([]); setWC(null); };

        if (state === 'idle') {
            return wp.element.createElement('button', {
                className: 'sch-detect-btn', onClick: detect
            }, '🤖 Auto-detect Schema Types');
        }

        if (state === 'loading') {
            return wp.element.createElement('div', { className: 'sch-detect-loading' },
                wp.element.createElement(Spinner, { style: { width: '14px', height: '14px', margin: 0 } }),
                wp.element.createElement('span', null, 'Analysing content…')
            );
        }

        // state === 'done'
        return wp.element.createElement('div', { className: 'sch-detect-result' },
            wp.element.createElement('div', { className: 'sch-detect-result__header' },
                wp.element.createElement('span', { className: 'sch-label' },
                    recs.length > 0 ? `Detected (${recs.length}):` : 'No specific type detected'
                ),
                wp.element.createElement('button', { className: 'sch-refresh-btn', onClick: reset, title: 'Reset' },
                    wp.element.createElement(Icon, { icon: 'no-alt', style: { width: '11px', height: '11px' } })
                )
            ),
            wordCount !== null && wp.element.createElement('span', {
                className: `sch-word-count ${wordCount < 20 ? 'is-red' : wordCount < 80 ? 'is-amber' : wordCount < 300 ? 'is-blue' : 'is-green'}`
            }, `${wordCount} words`),
            recs.length > 0 && wp.element.createElement('div', { className: 'sch-detect-chips' },
                recs.slice(0, 6).map(rec =>
                    wp.element.createElement('button', {
                        key: rec.type,
                        className: 'sch-detect-chip',
                        onClick: () => openAdmin('builder', postUrl),
                        title: rec.reason || rec.type
                    },
                        wp.element.createElement('span', null, schemaInfo(rec.type).icon),
                        wp.element.createElement('span', null, ' ' + rec.type),
                        wp.element.createElement('span', { className: 'sch-detect-chip__score' },
                            `${Math.round((rec.confidence || 0) * 100)}%`
                        )
                    )
                )
            )
        );
    };

    // ─── EditorPicker (inline — no Modal) ─────────────────────────────────────

    const EditorPicker = ({ schema, postUrl, onClose }) => {
        const editing = !!schema;
        const info    = schema ? schemaInfo(schema.schema_type) : null;

        const go = tab => {
            const p = new URLSearchParams({ tab });
            if (postUrl) p.set('url', postUrl);
            if (editing && schema.id) p.set('edit_id', schema.id);
            window.open(`${adminUrl}&${p}`, '_blank');
            onClose();
        };

        return wp.element.createElement('div', { className: 'sch-picker' },
            wp.element.createElement('div', { className: 'sch-picker__header' },
                wp.element.createElement('span', { className: 'sch-picker__title' },
                    editing ? `Edit: ${schema.schema_name}` : 'Add New Schema'
                ),
                wp.element.createElement('button', { className: 'sch-picker__close', onClick: onClose, 'aria-label': 'Close' },
                    wp.element.createElement(Icon, { icon: 'no-alt', style: { width: '14px', height: '14px' } })
                )
            ),
            editing && info && wp.element.createElement('div', { className: 'sch-picker__meta' },
                wp.element.createElement('span', null, info.icon),
                wp.element.createElement('span', { style: { fontSize: '12px', color: '#6b7280' } }, schema.schema_type)
            ),
            wp.element.createElement('p', { className: 'sch-picker__hint' },
                editing ? 'Choose your preferred editor:' : 'How would you like to create it?'
            ),
            wp.element.createElement('div', { className: 'sch-picker__grid' },
                wp.element.createElement('button', { className: 'sch-picker-card', onClick: () => go('builder') },
                    wp.element.createElement('span', { className: 'sch-picker-card__icon' }, '🧱'),
                    wp.element.createElement('strong', null, 'Smart Builder'),
                    wp.element.createElement('span', { className: 'sch-picker-card__desc' }, 'Visual form editor with guided fields.')
                ),
                wp.element.createElement('button', { className: 'sch-picker-card', onClick: () => go('manual') },
                    wp.element.createElement('span', { className: 'sch-picker-card__icon' }, '{ }'),
                    wp.element.createElement('strong', null, 'Manual JSON'),
                    wp.element.createElement('span', { className: 'sch-picker-card__desc' }, 'Full JSON-LD for advanced users.')
                )
            ),
            postUrl && wp.element.createElement('div', { className: 'sch-picker__url' },
                wp.element.createElement(Icon, { icon: 'admin-links', style: { width: '11px', height: '11px', flexShrink: 0, color: '#4f46e5' } }),
                wp.element.createElement('span', null, postUrl)
            )
        );
    };

    // ─── SchemaRow ─────────────────────────────────────────────────────────────

    const SchemaRow = ({ schema, isExpanded, isJsonOpen, onEdit, onJsonToggle, onToggle, onDelete }) => {
        const [busy, setBusy] = useState(false);
        const active = parseInt(schema.is_active) === 1;
        const info   = schemaInfo(schema.schema_type);
        const wrap   = async fn => { setBusy(true); try { await fn(); } catch(e){} setBusy(false); };

        return wp.element.createElement(Fragment, null,
            wp.element.createElement('div', { className: `sch-schema-row${active ? ' is-active' : ''}${isExpanded ? ' is-expanded' : ''}` },
                wp.element.createElement('span', { className: 'sch-schema-row__icon' }, info.icon),
                wp.element.createElement('div', { className: 'sch-schema-row__info' },
                    wp.element.createElement('div', { className: 'sch-schema-row__name' }, schema.schema_name),
                    wp.element.createElement('div', { className: 'sch-schema-row__type' }, schema.schema_type)
                ),
                wp.element.createElement('span', { className: `sch-dot${active ? ' sch-dot--on' : ' sch-dot--off'}` }),
                wp.element.createElement('div', { className: 'sch-schema-row__actions' },
                    // JSON preview toggle
                    schema.schema_data && wp.element.createElement('button', {
                        className: `sch-icon-btn${isJsonOpen ? ' sch-icon-btn--active' : ''}`,
                        onClick: () => onJsonToggle(schema.id),
                        title: isJsonOpen ? 'Hide JSON' : 'Preview JSON-LD'
                    }, wp.element.createElement(Icon, { icon: 'editor-code', style: { width: '13px', height: '13px' } })),
                    // Edit
                    wp.element.createElement('button', {
                        className: `sch-icon-btn${isExpanded ? ' sch-icon-btn--active' : ''}`,
                        onClick: () => onEdit(schema), disabled: busy, title: 'Edit'
                    }, wp.element.createElement(Icon, { icon: isExpanded ? 'arrow-up-alt2' : 'edit', style: { width: '13px', height: '13px' } })),
                    // Toggle active
                    wp.element.createElement('button', {
                        className: `sch-icon-btn${!active ? ' sch-icon-btn--muted' : ''}`,
                        onClick: () => wrap(() => onToggle(schema.id)), disabled: busy, title: active ? 'Deactivate' : 'Activate'
                    }, busy
                        ? wp.element.createElement(Spinner, { style: { width: '13px', height: '13px', margin: 0 } })
                        : wp.element.createElement(Icon, { icon: active ? 'controls-pause' : 'controls-play', style: { width: '13px', height: '13px' } })
                    ),
                    // Delete
                    wp.element.createElement('button', {
                        className: 'sch-icon-btn sch-icon-btn--danger',
                        onClick: () => { if (confirm('Delete this schema?')) wrap(() => onDelete(schema.id)); },
                        disabled: busy, title: 'Delete'
                    }, wp.element.createElement(Icon, { icon: 'trash', style: { width: '13px', height: '13px' } }))
                )
            ),
            // Inline JSON viewer
            isJsonOpen && schema.schema_data && wp.element.createElement(JsonViewer, { jsonString: schema.schema_data })
        );
    };

    // ─── SEOTab ────────────────────────────────────────────────────────────────

    const SEOTab = () => {
        const postType    = useSelect(s => s('core/editor').getCurrentPostType(), []);
        const postTitle   = useSelect(s => s('core/editor').getEditedPostAttribute('title'), []);
        const postContent = useSelect(s => s('core/editor').getEditedPostAttribute('content'), []);
        const postExcerpt = useSelect(s => s('core/editor').getEditedPostAttribute('excerpt'), []);
        const postUrl     = usePostUrl();

        const [meta, setMeta] = useEntityProp('postType', postType, 'meta');

        // When another SEO plugin owns these fields, its panel in this same
        // editor is the one place they are edited. Schemafy reads the shared
        // value for its preview and score, but draws no duplicate input.
        const metaOwner = cfg.metaOwner || '';
        const ownerVals = cfg.metaOwnerValues || {};

        const metaTitle = metaOwner
            ? (ownerVals.title || '')
            : ((meta && meta._schemafy_custom_meta_title) || '');
        const metaDesc  = metaOwner
            ? (ownerVals.description || '')
            : ((meta && meta._schemafy_custom_meta_description) || '');

        const [keyword, setKeyword] = useState('');
        const [device,  setDevice]  = useState('desktop');
        const [inited,  setInited]  = useState(false);

        useEffect(() => {
            if (meta && !inited) {
                if (meta._schemafy_focus_keyword) setKeyword(meta._schemafy_focus_keyword);
                setInited(true);
            }
        }, [meta, inited]);

        const updateMeta = useCallback((key, val) => {
            if (setMeta && meta !== undefined) setMeta({ ...(meta || {}), [key]: val });
        }, [meta, setMeta]);

        useEffect(() => { if (inited) updateMeta('_schemafy_focus_keyword', keyword); }, [keyword, inited]);

        const titleLen = (metaTitle || postTitle || '').length;
        const descLen  = metaDesc.length;

        // Keyword analysis
        const kw          = keyword.trim().toLowerCase();
        const contentText = (postContent || '').replace(/<[^>]+>/g, ' ').toLowerCase();
        const kwInTitle   = kw && (metaTitle || postTitle || '').toLowerCase().includes(kw);
        const kwInDesc    = kw && metaDesc.toLowerCase().includes(kw);
        const kwInContent = kw && contentText.includes(kw);
        const showKwRow   = !!kw;

        return wp.element.createElement('div', { className: 'sch-tab-content' },

            // ── Focus Keyword ────────────────────────────────────────────────
            wp.element.createElement('div', { className: 'sch-section' },
                wp.element.createElement('label', { className: 'sch-label' }, 'Focus Keyword'),
                wp.element.createElement(TextControl, {
                    value: keyword, onChange: setKeyword,
                    placeholder: 'e.g. best plumber chicago',
                    __nextHasNoMarginBottom: true
                }),
                showKwRow && wp.element.createElement('div', { className: 'sch-kw-row' },
                    wp.element.createElement(KwBadge, { label: 'Title',       found: kwInTitle   }),
                    wp.element.createElement(KwBadge, { label: 'Description', found: kwInDesc    }),
                    wp.element.createElement(KwBadge, { label: 'Content',     found: kwInContent })
                )
            ),

            wp.element.createElement('div', { className: 'sch-divider' }),

            // ── Snippet Preview ──────────────────────────────────────────────
            wp.element.createElement('div', { className: 'sch-section' },
                wp.element.createElement('div', { className: 'sch-section-header' },
                    wp.element.createElement('span', { className: 'sch-label' }, 'Snippet Preview'),
                    wp.element.createElement('div', { className: 'sch-device-toggle' },
                        ['desktop', 'mobile'].map(d =>
                            wp.element.createElement('button', {
                                key: d, title: d,
                                className: `sch-device-btn${device === d ? ' is-active' : ''}`,
                                onClick: () => setDevice(d)
                            }, wp.element.createElement(Icon, {
                                icon: d === 'desktop' ? 'desktop' : 'smartphone',
                                style: { width: '14px', height: '14px' }
                            }))
                        )
                    )
                ),
                wp.element.createElement(GooglePreview, {
                    title:       metaTitle || postTitle,
                    description: metaDesc  || postExcerpt,
                    url: postUrl, device
                })
            ),

            wp.element.createElement('div', { className: 'sch-divider' }),

            // ── SEO Title / Meta Description ─────────────────────────────────
            metaOwner
                ? wp.element.createElement('div', { className: 'sch-note' },
                    'SEO title and meta description are managed by ' + metaOwner +
                    ' on this site. Edit them in its panel and they apply here too — ' +
                    'Schemafy reads and writes the same values.'
                  )
                : wp.element.createElement(wp.element.Fragment, null,
                    wp.element.createElement('div', { className: 'sch-section' },
                        wp.element.createElement('label', { className: 'sch-label' }, 'SEO Title'),
                        wp.element.createElement(TextControl, {
                            value: metaTitle,
                            onChange: v => updateMeta('_schemafy_custom_meta_title', v),
                            placeholder: postTitle || 'Enter your SEO title…',
                            __nextHasNoMarginBottom: true
                        }),
                        wp.element.createElement(CharPill, { count: titleLen, min: 50, max: 60 })
                    ),
                    wp.element.createElement('div', { className: 'sch-section' },
                        wp.element.createElement('label', { className: 'sch-label' }, 'Meta Description'),
                        wp.element.createElement(TextareaControl, {
                            value: metaDesc,
                            onChange: v => updateMeta('_schemafy_custom_meta_description', v),
                            placeholder: 'Write a compelling meta description…',
                            rows: 3, __nextHasNoMarginBottom: true
                        }),
                        wp.element.createElement(CharPill, { count: descLen, min: 120, max: 160 })
                    ),
                    wp.element.createElement('div', { className: 'sch-note' },
                        'Values are saved automatically when you publish or update.'
                    )
                  )
        );
    };

    // ─── SocialTab ─────────────────────────────────────────────────────────────

    const SocialTab = () => {
        const postType    = useSelect(s => s('core/editor').getCurrentPostType(), []);
        const postTitle   = useSelect(s => s('core/editor').getEditedPostAttribute('title'), []);
        const postExcerpt = useSelect(s => s('core/editor').getEditedPostAttribute('excerpt'), []);
        const postUrl     = usePostUrl();

        const [meta, setMeta] = useEntityProp('postType', postType, 'meta');
        const [panel, setPanel] = useState('facebook');

        const og = {
            title:       (meta && meta._schemafy_og_title)              || '',
            description: (meta && meta._schemafy_og_description)        || '',
            image:       (meta && meta._schemafy_og_image)              || '',
            type:        (meta && meta._schemafy_og_type)               || 'website'
        };
        const tw = {
            title:       (meta && meta._schemafy_twitter_title)         || '',
            description: (meta && meta._schemafy_twitter_description)   || '',
            image:       (meta && meta._schemafy_twitter_image)         || '',
            card:        (meta && meta._schemafy_twitter_card)          || 'summary_large_image',
            creator:     (meta && meta._schemafy_twitter_creator)       || ''
        };

        const set = (key, val) => {
            if (setMeta && meta !== undefined) setMeta({ ...(meta || {}), [key]: val });
        };

        const fbTitle   = og.title       || postTitle   || 'Page title';
        const fbDesc    = og.description || postExcerpt || 'Page description';
        const twTitle   = tw.title       || og.title    || postTitle   || 'Page title';
        const twDesc    = tw.description || og.description || postExcerpt || 'Page description';
        const twImage   = tw.image       || og.image    || '';

        return wp.element.createElement('div', { className: 'sch-tab-content' },

            wp.element.createElement('div', { className: 'sch-social-tabs' },
                wp.element.createElement('button', {
                    className: `sch-social-tab${panel === 'facebook' ? ' is-active' : ''}`,
                    onClick: () => setPanel('facebook')
                },
                    wp.element.createElement('span', { className: 'sch-social-tab__icon sch-social-tab__icon--fb' }, 'f'),
                    'Facebook'
                ),
                wp.element.createElement('button', {
                    className: `sch-social-tab${panel === 'twitter' ? ' is-active' : ''}`,
                    onClick: () => setPanel('twitter')
                },
                    wp.element.createElement('span', { className: 'sch-social-tab__icon sch-social-tab__icon--tw' }, '𝕏'),
                    'Twitter / X'
                )
            ),

            panel === 'facebook' && wp.element.createElement(Fragment, null,
                wp.element.createElement('div', { className: 'sch-section' },
                    wp.element.createElement('label', { className: 'sch-label' }, 'Facebook Preview'),
                    wp.element.createElement(FbPreview, { title: fbTitle, description: fbDesc, image: og.image, url: postUrl })
                ),
                wp.element.createElement('div', { className: 'sch-divider' }),
                wp.element.createElement('div', { className: 'sch-section' },
                    wp.element.createElement(ImageField, {
                        label: 'OG Image', value: og.image, onChange: v => set('_schemafy_og_image', v)
                    }),
                    wp.element.createElement('div', { style: { marginTop: '12px' } },
                        wp.element.createElement('label', { className: 'sch-label' }, 'OG Title'),
                        wp.element.createElement(TextControl, {
                            value: og.title, onChange: v => set('_schemafy_og_title', v),
                            placeholder: postTitle || 'Title for Facebook…', __nextHasNoMarginBottom: true
                        })
                    ),
                    wp.element.createElement('div', { style: { marginTop: '10px' } },
                        wp.element.createElement('label', { className: 'sch-label' }, 'OG Description'),
                        wp.element.createElement(TextareaControl, {
                            value: og.description, onChange: v => set('_schemafy_og_description', v),
                            placeholder: 'Description for Facebook…', rows: 2, __nextHasNoMarginBottom: true
                        })
                    )
                )
            ),

            panel === 'twitter' && wp.element.createElement(Fragment, null,
                wp.element.createElement('div', { className: 'sch-section' },
                    wp.element.createElement('div', { className: 'sch-section-header' },
                        wp.element.createElement('label', { className: 'sch-label' }, 'Twitter Preview'),
                        wp.element.createElement(SelectControl, {
                            value: tw.card, onChange: v => set('_schemafy_twitter_card', v),
                            options: [
                                { value: 'summary_large_image', label: 'Large image' },
                                { value: 'summary',             label: 'Summary'     }
                            ],
                            __nextHasNoMarginBottom: true,
                            style: { fontSize: '11px', height: '28px', padding: '0 4px', marginBottom: 0 }
                        })
                    ),
                    wp.element.createElement(TwitterPreview, {
                        title: twTitle, description: twDesc, image: twImage, url: postUrl, cardType: tw.card
                    })
                ),
                wp.element.createElement('div', { className: 'sch-divider' }),
                wp.element.createElement('div', { className: 'sch-section' },
                    wp.element.createElement(ImageField, {
                        label: 'Twitter Image', value: tw.image, onChange: v => set('_schemafy_twitter_image', v)
                    }),
                    wp.element.createElement('div', { style: { marginTop: '12px' } },
                        wp.element.createElement('label', { className: 'sch-label' }, 'Twitter Title'),
                        wp.element.createElement(TextControl, {
                            value: tw.title, onChange: v => set('_schemafy_twitter_title', v),
                            placeholder: og.title || postTitle || 'Title for Twitter…', __nextHasNoMarginBottom: true
                        })
                    ),
                    wp.element.createElement('div', { style: { marginTop: '10px' } },
                        wp.element.createElement('label', { className: 'sch-label' }, 'Twitter Description'),
                        wp.element.createElement(TextareaControl, {
                            value: tw.description, onChange: v => set('_schemafy_twitter_description', v),
                            placeholder: og.description || postExcerpt || 'Description for Twitter…', rows: 2, __nextHasNoMarginBottom: true
                        })
                    ),
                    wp.element.createElement('div', { style: { marginTop: '10px' } },
                        wp.element.createElement('label', { className: 'sch-label' }, '@Creator handle'),
                        wp.element.createElement(TextControl, {
                            value: tw.creator, onChange: v => set('_schemafy_twitter_creator', v),
                            placeholder: '@yourhandle', __nextHasNoMarginBottom: true
                        })
                    )
                )
            ),

            wp.element.createElement('div', { className: 'sch-note', style: { marginTop: '4px' } },
                'Saved automatically when you publish or update.'
            )
        );
    };

    // ─── SchemaTab ─────────────────────────────────────────────────────────────

    const SchemaTab = () => {
        const postUrl    = usePostUrl();
        const postId     = usePostId();
        const [schemas,    setSchemas]    = useState([]);
        const [loading,    setLoading]    = useState(false);
        const [expandedId, setExpandedId] = useState(null); // schema.id | 'new' | null
        const [jsonOpenId, setJsonOpenId] = useState(null); // schema.id | null
        const [toast,      setToast]      = useState('');

        const flash = msg => { setToast(msg); setTimeout(() => setToast(''), 2800); };

        const load = useCallback(async () => {
            if (!postUrl) return;
            setLoading(true);
            try {
                const res = await apiFetch({ path: `schemafy/v1/schemas-by-url?url=${encodeURIComponent(postUrl)}` });
                setSchemas(Array.isArray(res.schemas) ? res.schemas : []);
            } catch(e) { setSchemas([]); }
            setLoading(false);
        }, [postUrl]);

        useEffect(() => { if (postUrl) load(); }, [postUrl]);

        const handleToggle    = async id => { await apiFetch({ path: `schemafy/v1/schemas/${id}/toggle`, method: 'POST' }); await load(); flash('Schema updated'); };
        const handleDelete    = async id => { await apiFetch({ path: `schemafy/v1/schemas/${id}`, method: 'DELETE' }); setExpandedId(null); setJsonOpenId(null); await load(); flash('Schema deleted'); };
        const handleEdit      = schema => { setExpandedId(prev => prev === schema.id ? null : schema.id); setJsonOpenId(null); };
        const handleClose     = () => { setExpandedId(null); load(); };
        const handleJsonToggle = id => { setJsonOpenId(prev => prev === id ? null : id); setExpandedId(null); };

        const handleExport = () => {
            if (!schemas.length) return;
            const hostname = postUrl ? new URL(postUrl).hostname : 'schemas';
            downloadJson({ schemas }, `schemafy-${hostname}.json`);
        };

        const activeCount = schemas.filter(s => parseInt(s.is_active) === 1).length;

        return wp.element.createElement('div', { className: 'sch-tab-content' },

            toast && wp.element.createElement('div', { className: 'sch-toast' }, '✓ ' + toast),

            // ── Schema list ─────────────────────────────────────────────────
            wp.element.createElement('div', { className: 'sch-section' },
                wp.element.createElement('div', { className: 'sch-section-header' },
                    wp.element.createElement('span', { className: 'sch-label' },
                        schemas.length > 0 ? `Schemas (${activeCount}/${schemas.length} active)` : 'Schemas on this page'
                    ),
                    wp.element.createElement('div', { style: { display: 'flex', gap: '2px', alignItems: 'center' } },
                        // Export button
                        schemas.length > 0 && wp.element.createElement('button', {
                            className: 'sch-icon-btn', onClick: handleExport, title: 'Export schemas as JSON'
                        }, wp.element.createElement(Icon, { icon: 'download', style: { width: '13px', height: '13px' } })),
                        // Refresh
                        wp.element.createElement('button', {
                            className: 'sch-refresh-btn', onClick: load, disabled: loading, title: 'Refresh'
                        }, wp.element.createElement(Icon, { icon: 'update', style: { width: '12px', height: '12px' } }))
                    )
                ),

                // URL pill + Test in Google link
                postUrl && wp.element.createElement('div', { className: 'sch-url-row' },
                    wp.element.createElement('div', { className: 'sch-url-pill' }, postUrl),
                    wp.element.createElement('a', {
                        href: `https://search.google.com/test/rich-results?url=${encodeURIComponent(postUrl)}`,
                        target: '_blank', rel: 'noopener noreferrer',
                        className: 'sch-test-link', title: 'Test rich results in Google'
                    },
                        wp.element.createElement(Icon, { icon: 'external', style: { width: '11px', height: '11px' } }),
                        'Test'
                    )
                ),

                loading
                    ? wp.element.createElement('div', { className: 'sch-spinner-wrap' }, wp.element.createElement(Spinner))
                    : schemas.length === 0
                        ? wp.element.createElement('div', { className: 'sch-empty' },
                            wp.element.createElement('div', { className: 'sch-empty__icon' }, '🗂'),
                            wp.element.createElement('p', null, postUrl ? 'No schemas yet for this page.' : 'Save the post first.'),
                            postUrl && expandedId !== 'new' && wp.element.createElement('button', {
                                className: 'sch-add-btn sch-add-btn--primary',
                                onClick: () => setExpandedId('new')
                            }, '+ Add First Schema')
                          )
                        : wp.element.createElement('div', { className: 'sch-schema-list' },
                            schemas.map(s =>
                                wp.element.createElement(Fragment, { key: s.id },
                                    wp.element.createElement(SchemaRow, {
                                        schema: s,
                                        isExpanded: expandedId === s.id,
                                        isJsonOpen: jsonOpenId === s.id,
                                        onEdit: handleEdit,
                                        onJsonToggle: handleJsonToggle,
                                        onToggle: handleToggle,
                                        onDelete: handleDelete
                                    }),
                                    expandedId === s.id && wp.element.createElement(EditorPicker, {
                                        schema: s, postUrl, onClose: handleClose
                                    })
                                )
                            )
                          ),

                !loading && schemas.length > 0 && expandedId !== 'new' &&
                    wp.element.createElement('button', {
                        className: 'sch-add-btn', style: { marginTop: '8px' },
                        onClick: () => setExpandedId('new')
                    }, '+ Add Schema'),

                expandedId === 'new' && wp.element.createElement(EditorPicker, {
                    schema: null, postUrl, onClose: handleClose
                })
            ),

            wp.element.createElement('div', { className: 'sch-divider' }),

            // ── Auto-detect ──────────────────────────────────────────────────
            postId && wp.element.createElement('div', { className: 'sch-section' },
                wp.element.createElement('div', { className: 'sch-label sch-label--mb' }, 'Schema Detection'),
                wp.element.createElement(AutoDetect, { postId, postUrl })
            ),

            wp.element.createElement('div', { className: 'sch-divider' }),

            // ── Quick links ─────────────────────────────────────────────────
            wp.element.createElement('div', { className: 'sch-section' },
                wp.element.createElement('div', { className: 'sch-label sch-label--mb' }, 'Open in Plugin'),
                wp.element.createElement('div', { className: 'sch-quicklinks' },
                    [
                        { label: 'Smart Builder',  icon: '🧱', tab: 'builder'        },
                        { label: 'AI Generator',   icon: '✨', tab: 'ai'             },
                        { label: 'Auto Generator', icon: '🤖', tab: 'auto-generator' },
                        { label: 'Manual JSON',    icon: '{}', tab: 'manual'         },
                        { label: 'Meta Tags',      icon: '🏷',  tab: 'meta-tags'     },
                        { label: 'Dashboard',      icon: '📊', tab: 'dashboard'      }
                    ].map(({ label, icon, tab }) =>
                        wp.element.createElement('button', {
                            key: tab, className: 'sch-quicklink',
                            onClick: () => openAdmin(tab, postUrl)
                        },
                            wp.element.createElement('span', { className: 'sch-quicklink__icon' }, icon),
                            wp.element.createElement('span', null, label),
                            wp.element.createElement(Icon, { icon: 'external', style: { width: '11px', height: '11px', marginLeft: 'auto', color: '#9ca3af' } })
                        )
                    )
                )
            )
        );
    };

    // ─── Root ──────────────────────────────────────────────────────────────────

    const SchemafySidebar = () => {
        const [tab, setTab] = useState('seo');
        const isDirty = useSelect(s => s('core/editor').isEditedPostDirty(), []);

        const TABS = [
            { id: 'seo',    label: 'SEO'    },
            { id: 'social', label: 'Social' },
            { id: 'schema', label: 'Schema' }
        ];

        return wp.element.createElement(Fragment, null,
            wp.element.createElement(PluginSidebarMoreMenuItem, { target: 'schemafy-sidebar', icon: 'chart-line' }, 'Schemafy'),
            wp.element.createElement(PluginSidebar, {
                name: 'schemafy-sidebar', title: 'Schemafy',
                icon: 'chart-line', className: 'schemafy-sidebar sch-sidebar'
            },
                // Header
                wp.element.createElement('div', { className: 'sch-header' },
                    wp.element.createElement('div', { className: 'sch-header__logo' },
                        wp.element.createElement('svg', { width: '18', height: '18', viewBox: '0 0 24 24', fill: 'none' },
                            wp.element.createElement('path', {
                                d: 'M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5',
                                stroke: '#fff', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round'
                            })
                        ),
                        'Schemafy'
                    ),
                    wp.element.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '6px' } },
                        isDirty && wp.element.createElement('span', { className: 'sch-dirty-badge' }, '● Unsaved'),
                        cfg.version && wp.element.createElement('span', { className: 'sch-header__version' }, `v${cfg.version}`)
                    )
                ),

                // Tabs
                wp.element.createElement('div', { className: 'sch-tabs' },
                    TABS.map(t => wp.element.createElement('button', {
                        key: t.id,
                        className: `sch-tab${tab === t.id ? ' is-active' : ''}`,
                        onClick: () => setTab(t.id)
                    }, t.label))
                ),

                tab === 'seo'    ? wp.element.createElement(SEOTab)    : null,
                tab === 'social' ? wp.element.createElement(SocialTab) : null,
                tab === 'schema' ? wp.element.createElement(SchemaTab) : null
            )
        );
    };

    registerPlugin('schemafy-sidebar', { render: SchemafySidebar, icon: 'chart-line' });

})(window.wp);
