'use client';
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
/**
 * Inline SEO editor pane for the post/page section editors and the Content SEO
 * list. Accordion sections mirror Yoast-style workflow: Focus Keyword → Search
 * Appearance → Social → Analysis → Advanced → Insights → Linking.
 */
import { cloneElement, isValidElement, useEffect, useId, useMemo, useState, } from 'react';
import { Loader2, Monitor, Smartphone, Sparkles, Wand2 } from 'lucide-react';
import { toast } from 'sonner';
import { resolveRenderedMetaTitle } from '@actuate-media/cms-core/client';
import { analyzeContent, calculateReadability, stripHtmlTags, } from '@actuate-media/cms-core/seo/analysis';
import { fetchSeoContentRecord, updateSeoFields, generateSeoField, fetchDocumentSeoAnalysis, SEO_SCHEMA_TYPES, } from '../../lib/seo-service.js';
import { fixBrandVoiceContent } from '../../lib/brand-voice-client.js';
import { BrandVoiceAlignmentBadge } from '../BrandVoiceAlignmentBadge.js';
import { InspectorPaneBody, InspectorPaneFooter, InspectorPaneHeader } from '../ui/InspectorPane.js';
import { Toggle } from '../ui/Toggle.js';
import { SeoLoading, SeoErrorState, gradeMeta } from './primitives.js';
import { SeoAccordion, SeoAccordionBadge, SeoAccordionItem } from './SeoAccordion.js';
import { SeoAnalysisList } from './SeoAnalysisList.js';
import { SeoInsightsMetrics } from './SeoInsightsMetrics.js';
import { SeoLinkingSection } from './SeoLinkingSection.js';
const META_TITLE_MAX = 60;
const META_DESC_MAX = 160;
const KEY_TAKEAWAY_MAX = 240;
const LLMS_DESC_MAX = 160;
function seoBrandChannel(field) {
    if (field === 'metaDescription' || field === 'ogDescription')
        return 'meta_description';
    return undefined;
}
const inputCls = 'w-full rounded-[7px] border border-[var(--bdr)] bg-[var(--card)] px-2.5 py-1.5 text-[12.5px] text-[var(--txt)] placeholder:text-[var(--muted)] focus:border-[var(--acc)] focus:outline-none';
function CharCount({ value, max }) {
    const over = value.length > max;
    return (_jsxs("span", { className: `text-[11px] ${over ? 'text-[var(--err)]' : 'text-[var(--muted)]'}`, children: [value.length, "/", max] }));
}
function PaneField({ label, children, hint, help, }) {
    const generatedId = useId();
    let control = children;
    if (isValidElement(children) && children.props.id == null) {
        control = cloneElement(children, { id: generatedId });
    }
    const controlId = isValidElement(control) ? control.props.id : undefined;
    return (_jsxs("div", { className: "mb-3 last:mb-0", children: [_jsxs("div", { className: "mb-1 flex items-center justify-between gap-2", children: [_jsx("label", { htmlFor: controlId, className: "text-[11.5px] font-medium text-[var(--sub)]", children: label }), hint] }), control, help && _jsx("p", { className: "mt-1 text-[11px] text-[var(--muted)]", children: help })] }));
}
function PaneToggleRow({ label, hint, checked, onCheckedChange, }) {
    return (_jsxs("div", { className: "flex items-center justify-between gap-3 py-1.5", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-[12.5px] font-medium text-[var(--txt)]", children: label }), _jsx("div", { className: "text-[11px] text-[var(--muted)]", children: hint })] }), _jsx(Toggle, { checked: checked, onCheckedChange: onCheckedChange, "aria-label": label })] }));
}
export function SeoEditorPane({ entityType, entityId, onClose, onSaved, contentHtml = '', slug = '', draftMeta, onDraftChange, }) {
    const isDraft = !entityId;
    const [record, setRecord] = useState(null);
    const [loading, setLoading] = useState(!isDraft);
    const [error, setError] = useState(null);
    const [saving, setSaving] = useState(false);
    const [aiBusy, setAiBusy] = useState(null);
    const [aiFixBusy, setAiFixBusy] = useState(null);
    const [aiAlignments, setAiAlignments] = useState({});
    const [form, setForm] = useState({});
    const [previewDevice, setPreviewDevice] = useState('mobile');
    const [socialPlatform, setSocialPlatform] = useState('facebook');
    const [remoteAnalysis, setRemoteAnalysis] = useState(null);
    useEffect(() => {
        if (isDraft) {
            setLoading(false);
            setRecord(null);
            setError(null);
            setForm({
                metaTitle: draftMeta?.seoTitle ?? '',
                metaDescription: draftMeta?.seoDescription ?? '',
                focusKeyword: '',
                keyTakeaway: '',
                ogTitle: '',
                ogDescription: '',
                canonicalUrl: '',
                structuredDataType: 'WebPage',
                noindex: false,
                nofollow: false,
                llmsInclude: 'AUTO',
                llmsDescription: '',
                llmsSection: '',
                llmsOptional: false,
            });
            return;
        }
        let alive = true;
        setLoading(true);
        setError(null);
        fetchSeoContentRecord(entityType, entityId)
            .then((rec) => {
            if (!alive)
                return;
            if (!rec) {
                setError('Could not load this record.');
                return;
            }
            setRecord(rec);
            setForm({
                metaTitle: rec.metaTitlePage ?? '',
                metaDescription: rec.metaDescription ?? '',
                canonicalUrl: rec.canonicalUrl ?? '',
                focusKeyword: rec.focusKeyword ?? '',
                keyTakeaway: rec.keyTakeaway ?? '',
                ogTitle: rec.ogTitle ?? '',
                ogDescription: rec.ogDescription ?? '',
                twitterTitle: rec.twitterTitle ?? '',
                twitterDescription: rec.twitterDescription ?? '',
                structuredDataType: rec.structuredDataType ?? 'WebPage',
                noindex: rec.noindex,
                nofollow: rec.nofollow,
                llmsInclude: rec.llmsInclude ?? 'AUTO',
                llmsDescription: rec.llmsDescription ?? '',
                llmsSection: rec.llmsSection ?? '',
                llmsOptional: rec.llmsOptional ?? false,
            });
        })
            .catch((e) => alive && setError(e instanceof Error ? e.message : 'Failed to load'))
            .finally(() => alive && setLoading(false));
        return () => {
            alive = false;
        };
    }, [entityType, entityId, isDraft]);
    useEffect(() => {
        if (isDraft || contentHtml.trim() || !entityId)
            return;
        let alive = true;
        fetchDocumentSeoAnalysis(entityId)
            .then((result) => alive && setRemoteAnalysis(result))
            .catch(() => alive && setRemoteAnalysis(null));
        return () => {
            alive = false;
        };
    }, [entityId, isDraft, contentHtml]);
    const update = (patch) => {
        setForm((f) => {
            const next = { ...f, ...patch };
            if (isDraft && onDraftChange) {
                if ('metaTitle' in patch)
                    onDraftChange({ seoTitle: patch.metaTitle });
                if ('metaDescription' in patch)
                    onDraftChange({ seoDescription: patch.metaDescription });
            }
            return next;
        });
    };
    async function handleAiGenerate(field) {
        if (isDraft && !contentHtml.trim() && field !== 'focusKeyword') {
            toast.error('Add a title or body content before generating with AI.');
            return;
        }
        setAiBusy(field);
        try {
            if (isDraft) {
                toast.error('Save a draft first to use AI field generation with site knowledge.');
                return;
            }
            const result = await generateSeoField(field, { entityType, entityId: entityId });
            if (result.unavailable) {
                toast.error('AI is not configured. Add an AI provider to enable suggestions.');
                return;
            }
            if (result.text) {
                // Write the suggestion into the field the editor actually asked to
                // generate. Previously an OG title/description generate was remapped
                // onto metaTitle/metaDescription (and the OG field cleared), silently
                // destroying a hand-written search title with no undo. Social fields
                // still inherit meta at render time when left blank, so filling the OG
                // field explicitly is non-destructive and matches the button's intent.
                const patch = { [field]: result.text };
                update(patch);
                if (result.brandAlignment) {
                    setAiAlignments((prev) => ({ ...prev, [field]: result.brandAlignment }));
                }
                toast.success('AI suggestion applied — review before saving.');
            }
            else {
                toast.error('No suggestion was returned.');
            }
        }
        catch {
            toast.error('AI request failed.');
        }
        finally {
            setAiBusy(null);
        }
    }
    async function handleAiFix(field) {
        const text = form[field] ?? '';
        if (!text.trim())
            return;
        setAiFixBusy(field);
        try {
            const res = await fixBrandVoiceContent({
                content: text,
                channel: seoBrandChannel(field),
            });
            if (!res.ok || !res.result) {
                toast.error(res.error ?? 'Could not fix copy for brand voice.');
                return;
            }
            update({ [field]: res.result.text });
            setAiAlignments((prev) => ({ ...prev, [field]: res.result.afterScore }));
            toast.success('Copy adjusted to match brand voice.');
        }
        finally {
            setAiFixBusy(null);
        }
    }
    function alignmentRow(field) {
        const alignment = aiAlignments[field];
        if (!alignment)
            return null;
        const fixing = aiFixBusy === field;
        return (_jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-2", children: [_jsx(BrandVoiceAlignmentBadge, { alignment: alignment, compact: true }), alignment.score < 85 && (_jsxs("button", { type: "button", onClick: () => void handleAiFix(field), disabled: fixing || aiBusy !== null, className: "inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-[11.5px] font-medium text-[var(--acc)] transition-colors duration-[var(--motion-fast)] hover:bg-[var(--acc-l)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:opacity-60", children: [fixing ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin", "aria-hidden": true })) : (_jsx(Wand2, { className: "h-3.5 w-3.5", "aria-hidden": true })), "Fix for brand voice"] }))] }));
    }
    async function handleSave() {
        if (isDraft) {
            toast.success('SEO fields will be saved with the document.');
            onClose();
            return;
        }
        setSaving(true);
        const res = await updateSeoFields(entityType, entityId, form);
        setSaving(false);
        if (res.error) {
            toast.error(res.error);
            return;
        }
        toast.success('SEO fields saved.');
        onSaved?.();
    }
    const renderedTitle = useMemo(() => {
        if (isDraft)
            return form.metaTitle?.trim() || draftMeta?.seoTitle || 'Untitled';
        if (!record)
            return form.metaTitle?.trim() || 'Untitled';
        return resolveRenderedMetaTitle({
            metaTitlePage: form.metaTitle,
            documentTitle: record.title,
            site: {
                siteName: record.siteName ?? undefined,
                titleTemplate: record.titleTemplate ?? undefined,
            },
        });
    }, [form.metaTitle, record, isDraft, draftMeta?.seoTitle]);
    const desc = form.metaDescription ||
        'Please provide a meta description. Search engines may generate one from your content.';
    const url = record?.url ?? (slug ? `/${slug.replace(/^\//, '')}` : '');
    const displayUrl = record?.url ?? url;
    const analysisInput = useMemo(() => ({
        title: record?.title ?? draftMeta?.seoTitle ?? '',
        slug: slug || record?.url?.split('/').filter(Boolean).pop() || '',
        content: contentHtml,
        // Measure the FULL rendered title (site template applied), matching what
        // the page score (`calculatePageSeoScore`) and the server /seo/analysis
        // endpoint measure — otherwise the meta-title-length check gives the
        // editor advice that contradicts the list score for the same field.
        metaTitle: renderedTitle,
        metaDescription: form.metaDescription,
        focusKeyphrase: form.focusKeyword,
        canonical: form.canonicalUrl,
        ogTitle: form.ogTitle,
        ogDescription: form.ogDescription,
        ogImage: record?.ogImage ?? undefined,
    }), [record, draftMeta, slug, contentHtml, form, renderedTitle]);
    const liveAnalysis = useMemo(() => {
        if (contentHtml.trim())
            return analyzeContent(analysisInput);
        return null;
    }, [analysisInput, contentHtml]);
    const analysis = liveAnalysis ?? remoteAnalysis;
    const plainText = stripHtmlTags(contentHtml);
    const readability = useMemo(() => calculateReadability(plainText), [plainText]);
    const problemCount = analysis?.checks.filter((c) => c.status === 'problem').length ?? 0;
    const internalLinks = analysis?.checks.find((c) => c.id === 'internal-links')?.description.match(/\d+/)?.[0] ?? '0';
    const externalLinks = analysis?.checks.find((c) => c.id === 'outbound-links')?.description.match(/\d+/)?.[0] ?? '0';
    const internalOk = Number(internalLinks) >= 1;
    const externalOk = Number(externalLinks) >= 1;
    function aiButton(field, label) {
        return (_jsxs("button", { type: "button", onClick: () => void handleAiGenerate(field), disabled: aiBusy !== null || isDraft, title: isDraft ? 'Save a draft first' : label, className: "inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[11px] font-medium text-[var(--acc)] transition-colors duration-[var(--motion-fast)] hover:bg-[var(--acc-l)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:opacity-60", children: [_jsx(Sparkles, { className: `h-3 w-3 ${aiBusy === field ? 'animate-pulse' : ''}`, "aria-hidden": true }), aiBusy === field ? 'Generating…' : 'AI Generate'] }));
    }
    const socialTitle = socialPlatform === 'twitter'
        ? form.twitterTitle || form.ogTitle || renderedTitle
        : form.ogTitle || renderedTitle;
    const socialDesc = socialPlatform === 'twitter'
        ? form.twitterDescription || form.ogDescription || form.metaDescription || desc
        : form.ogDescription || form.metaDescription || desc;
    return (_jsxs(_Fragment, { children: [_jsxs(InspectorPaneHeader, { onClose: onClose, closeLabel: "Close SEO editor", children: [_jsx("div", { className: "truncate text-[13.5px] font-semibold text-[var(--txt)]", children: record?.title ?? draftMeta?.seoTitle ?? 'SEO' }), displayUrl && (_jsx("div", { className: "mt-0.5 truncate text-[11.5px] text-[var(--muted)]", children: displayUrl }))] }), _jsx(InspectorPaneBody, { children: loading ? (_jsx("div", { className: "px-5 py-4", children: _jsx(SeoLoading, {}) })) : error ? (_jsx("div", { className: "px-5 py-4", children: _jsx(SeoErrorState, { message: error }) })) : (_jsxs(_Fragment, { children: [isDraft && (_jsx("div", { className: "border-b border-[var(--bdr)] px-5 py-3", children: _jsx("p", { className: "text-[11.5px] text-[var(--sub)]", children: "Save a draft to unlock AI assists trained on your site knowledge and tone. You can still set focus keyword, search appearance, and review live analysis below." }) })), !isDraft && record && (_jsx("div", { className: "border-b border-[var(--bdr)] px-5 py-3", children: (() => {
                                const meta = gradeMeta(record.seoGrade);
                                return (_jsx("div", { className: `flex items-center gap-2 rounded-[7px] px-3 py-2 text-[12px] ${meta.bg} ${meta.text}`, children: _jsxs("span", { children: ["SEO score: ", _jsx("span", { className: "font-medium", children: record.seoScore }), " (", meta.label, ")", analysis && (_jsxs(_Fragment, { children: [' · ', _jsxs("span", { title: "Content quality from the analysis checklist below (readability, keyphrase, links). Separate from the meta-weighted SEO score used to rank this list.", children: ["Content analysis ", analysis.score, "/100"] })] }))] }) }));
                            })() })), _jsxs(SeoAccordion, { children: [_jsxs(SeoAccordionItem, { value: "focus-keyword", title: "Focus keyword", badge: form.focusKeyword ? (_jsx(SeoAccordionBadge, { tone: "neutral", children: form.focusKeyword })) : (_jsx(SeoAccordionBadge, { tone: "warn", children: "Not set" })), children: [_jsx(PaneField, { label: "Focus keyphrase", hint: aiButton('focusKeyword', 'Suggest focus keyphrase'), help: "The main phrase you want this content found for in search and AI answers.", children: _jsx("input", { className: inputCls, value: form.focusKeyword ?? '', onChange: (e) => update({ focusKeyword: e.target.value }), placeholder: "e.g. modern headless cms" }) }), _jsx(PaneField, { label: "Key takeaway", hint: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(CharCount, { value: form.keyTakeaway ?? '', max: KEY_TAKEAWAY_MAX }), aiButton('keyTakeaway')] }), help: "One or two sentences AI answer engines can quote \u2014 what is this page about?", children: _jsx("textarea", { className: `${inputCls} min-h-16 resize-y`, value: form.keyTakeaway ?? '', onChange: (e) => update({ keyTakeaway: e.target.value }), placeholder: "Summarize the page's core value proposition" }) })] }), _jsxs(SeoAccordionItem, { value: "search-appearance", title: "Search appearance", children: [_jsx("p", { className: "text-[11.5px] text-[var(--sub)]", children: "Determine how this content should look in search results." }), _jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { className: "text-[11.5px] font-medium text-[var(--sub)]", children: "Google preview" }), _jsxs("div", { className: "flex rounded-[7px] border border-[var(--bdr)] p-0.5", children: [_jsxs("button", { type: "button", "aria-pressed": previewDevice === 'mobile', onClick: () => setPreviewDevice('mobile'), className: `inline-flex items-center gap-1 rounded-[5px] px-2 py-1 text-[11px] ${previewDevice === 'mobile' ? 'bg-[var(--acc-l)] text-[var(--acc)]' : 'text-[var(--muted)]'}`, children: [_jsx(Smartphone, { size: 14, "aria-hidden": true }), "Mobile"] }), _jsxs("button", { type: "button", "aria-pressed": previewDevice === 'desktop', onClick: () => setPreviewDevice('desktop'), className: `inline-flex items-center gap-1 rounded-[5px] px-2 py-1 text-[11px] ${previewDevice === 'desktop' ? 'bg-[var(--acc-l)] text-[var(--acc)]' : 'text-[var(--muted)]'}`, children: [_jsx(Monitor, { size: 14, "aria-hidden": true }), "Desktop"] })] })] }), _jsxs("div", { className: `rounded-[7px] border border-[var(--bdr)] bg-[var(--card)] p-3 ${previewDevice === 'mobile' ? 'max-w-[320px]' : ''}`, children: [_jsx("p", { className: "truncate text-[11px] text-[var(--suc)]", children: displayUrl }), _jsx("p", { className: "text-[15px] leading-snug text-[var(--acc)]", children: renderedTitle }), _jsx("p", { className: "line-clamp-2 text-[12px] text-[var(--sub)]", children: desc })] }), _jsx(PaneField, { label: "SEO title", hint: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(CharCount, { value: form.metaTitle ?? '', max: META_TITLE_MAX }), aiButton('metaTitle')] }), children: _jsx("input", { className: inputCls, value: form.metaTitle ?? '', onChange: (e) => update({ metaTitle: e.target.value }), placeholder: "Page-specific title (%page% in your site template)" }) }), alignmentRow('metaTitle'), _jsx(PaneField, { label: "Slug", help: "URL slug for this content \u2014 edit in page/post settings.", children: _jsx("input", { className: `${inputCls} opacity-80`, value: slug, readOnly: true, disabled: true }) }), _jsx(PaneField, { label: "Meta description", hint: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(CharCount, { value: form.metaDescription ?? '', max: META_DESC_MAX }), aiButton('metaDescription')] }), children: _jsx("textarea", { className: `${inputCls} min-h-20 resize-y`, value: form.metaDescription ?? '', onChange: (e) => update({ metaDescription: e.target.value }), placeholder: "Short summary shown under the title in search results" }) }), alignmentRow('metaDescription')] }), _jsxs(SeoAccordionItem, { value: "social-appearance", title: "Social appearance", children: [_jsx("p", { className: "text-[11.5px] text-[var(--sub)]", children: "Customize title, description, and image used when sharing on social platforms." }), _jsx("div", { className: "flex rounded-[7px] border border-[var(--bdr)] p-0.5", children: ['facebook', 'twitter'].map((platform) => (_jsx("button", { type: "button", "aria-pressed": socialPlatform === platform, onClick: () => setSocialPlatform(platform), className: `flex-1 rounded-[5px] px-2 py-1.5 text-[11.5px] font-medium capitalize ${socialPlatform === platform ? 'bg-[var(--acc-l)] text-[var(--acc)]' : 'text-[var(--sub)]'}`, children: platform === 'twitter' ? 'X / Twitter' : 'Facebook' }, platform))) }), _jsxs("div", { className: "overflow-hidden rounded-[7px] border border-[var(--bdr)]", children: [record?.ogImage ? (
                                                // eslint-disable-next-line @next/next/no-img-element
                                                _jsx("img", { src: record.ogImage, alt: "", className: "aspect-[1200/630] w-full bg-[var(--bg)] object-cover" })) : (_jsx("div", { className: "flex aspect-[1200/630] w-full items-center justify-center bg-[var(--bg)] text-[12px] text-[var(--muted)]", children: "No social image \u2014 add a featured or OG image" })), _jsxs("div", { className: "p-2.5", children: [_jsx("p", { className: "truncate text-[10.5px] text-[var(--muted)] uppercase", children: displayUrl.replace(/^https?:\/\//, '').split('/')[0] || 'yoursite.com' }), _jsx("p", { className: "truncate text-[12.5px] font-medium text-[var(--txt)]", children: socialTitle }), _jsx("p", { className: "line-clamp-2 text-[12px] text-[var(--sub)]", children: socialDesc })] })] }), socialPlatform === 'facebook' ? (_jsxs(_Fragment, { children: [_jsx(PaneField, { label: "OG title", hint: aiButton('ogTitle'), children: _jsx("input", { className: inputCls, value: form.ogTitle ?? '', onChange: (e) => update({ ogTitle: e.target.value }), placeholder: form.metaTitle || 'Inherits meta title when empty' }) }), _jsx(PaneField, { label: "OG description", hint: aiButton('ogDescription'), children: _jsx("textarea", { className: `${inputCls} min-h-16 resize-y`, value: form.ogDescription ?? '', onChange: (e) => update({ ogDescription: e.target.value }), placeholder: form.metaDescription || 'Inherits meta description when empty' }) })] })) : (_jsxs(_Fragment, { children: [_jsx(PaneField, { label: "Twitter title", children: _jsx("input", { className: inputCls, value: form.twitterTitle ?? '', onChange: (e) => update({ twitterTitle: e.target.value }), placeholder: form.ogTitle || form.metaTitle || 'Inherits OG/meta title' }) }), _jsx(PaneField, { label: "Twitter description", children: _jsx("textarea", { className: `${inputCls} min-h-16 resize-y`, value: form.twitterDescription ?? '', onChange: (e) => update({ twitterDescription: e.target.value }), placeholder: form.ogDescription ||
                                                            form.metaDescription ||
                                                            'Inherits OG/meta description' }) })] })), alignmentRow('ogDescription')] }), _jsx(SeoAccordionItem, { value: "seo-analysis", title: "SEO analysis", badge: analysis ? (_jsx(SeoAccordionBadge, { tone: problemCount > 0 ? 'bad' : 'good', children: problemCount > 0 ? `${problemCount} issues` : 'Looking good' })) : undefined, children: _jsx(SeoAnalysisList, { checks: analysis?.checks ?? [], onAiFixField: isDraft ? undefined : (field) => void handleAiGenerate(field), aiFixField: aiBusy }) }), _jsxs(SeoAccordionItem, { value: "advanced", title: "Advanced", children: [_jsx(PaneField, { label: "Canonical URL", children: _jsx("input", { className: inputCls, value: form.canonicalUrl ?? '', onChange: (e) => update({ canonicalUrl: e.target.value }), placeholder: displayUrl || 'https://example.com/page' }) }), !form.canonicalUrl?.trim() && displayUrl && !isDraft && (_jsxs("p", { className: "mb-3 text-[11px] text-[var(--muted)]", children: ["Auto-canonical: ", record?.canonicalUrl ?? displayUrl] })), _jsx(PaneField, { label: "Schema type", children: _jsx("select", { className: inputCls, value: form.structuredDataType ?? 'WebPage', onChange: (e) => update({ structuredDataType: e.target.value }), children: SEO_SCHEMA_TYPES.map((t) => (_jsx("option", { value: t, children: t }, t))) }) }), _jsx(PaneToggleRow, { label: "Allow search engines to show this content?", hint: "When off, adds a noindex directive", checked: !form.noindex, onCheckedChange: (v) => update({ noindex: !v }) }), _jsx(PaneToggleRow, { label: "Should search engines follow links?", hint: "When off, adds a nofollow directive", checked: !form.nofollow, onCheckedChange: (v) => update({ nofollow: !v }) }), _jsxs("div", { className: "mt-2 border-t border-[var(--bdr)] pt-3", children: [_jsx("p", { className: "mb-2 text-[11px] font-medium text-[var(--sub)]", children: "AI discovery (llms.txt)" }), _jsx(PaneField, { label: "Include in llms.txt", children: _jsxs("select", { className: inputCls, value: form.llmsInclude ?? 'AUTO', onChange: (e) => update({ llmsInclude: e.target.value }), children: [_jsx("option", { value: "AUTO", children: "Auto \u2014 include when eligible" }), _jsx("option", { value: "ALWAYS", children: "Always \u2014 pin it in" }), _jsx("option", { value: "NEVER", children: "Never \u2014 exclude" })] }) }), _jsx(PaneField, { label: "Agent description", hint: _jsx(CharCount, { value: form.llmsDescription ?? '', max: LLMS_DESC_MAX }), children: _jsx("textarea", { className: `${inputCls} min-h-16 resize-y`, value: form.llmsDescription ?? '', onChange: (e) => update({ llmsDescription: e.target.value }), placeholder: form.keyTakeaway ||
                                                            form.metaDescription ||
                                                            'One line for an AI agent — what this page covers' }) })] })] }), _jsx(SeoAccordionItem, { value: "insights", title: "Insights", children: _jsx(SeoInsightsMetrics, { readability: readability, plainText: plainText }) }), _jsx(SeoAccordionItem, { value: "linking-data", title: "Linking data", children: _jsx(SeoLinkingSection, { entityType: entityType, entityId: entityId, internalLinks: Number(internalLinks), externalLinks: Number(externalLinks), internalLinkOk: internalOk, externalLinkOk: externalOk }) })] })] })) }), _jsx(InspectorPaneFooter, { children: _jsx("button", { type: "button", onClick: () => void handleSave(), disabled: saving || loading || !!error, className: "bg-primary text-primary-foreground w-full rounded-[7px] px-3 py-2 text-[13px] font-semibold transition-colors duration-[var(--motion-fast)] hover:opacity-90 focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50", children: saving ? 'Saving…' : isDraft ? 'Done' : 'Save Changes' }) })] }));
}
//# sourceMappingURL=SeoEditorPane.js.map