'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useState } from 'react';
import { Eye, EyeOff, GripVertical, Lock, Plus, X } from 'lucide-react';
import { DndContext, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors, } from '@dnd-kit/core';
import { SortableContext, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy, } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { MediaPickerModal } from '../../components/MediaPickerModal.js';
import { blankRepeaterRow, getSectionType, resolveRepeaterField, } from './section-types.js';
const LABEL = 'text-foreground mb-1 block text-xs font-medium';
const INPUT = 'border-input bg-input-background text-foreground focus-visible:ring-ring w-full rounded-md border px-2.5 py-1.5 text-sm focus-visible:ring-2 focus-visible:outline-none';
export function SectionInspector({ section, canEdit, onClose, onContentChange, onSettingsChange, onMetaChange, onToggleVisibility, }) {
    const def = getSectionType(section.sectionType);
    // Escape closes the inspector.
    useEffect(() => {
        function onKey(e) {
            if (e.key === 'Escape')
                onClose();
        }
        document.addEventListener('keydown', onKey);
        return () => document.removeEventListener('keydown', onKey);
    }, [onClose]);
    // Unmanaged sections (no registered type) are read-only: show why instead of
    // editable controls, so the externally-managed content is never altered here.
    if (section.unmanaged) {
        return (_jsxs("aside", { role: "dialog", "aria-label": `${section.name} (read-only)`, className: "bg-card border-border flex h-full w-80 shrink-0 flex-col border-l", children: [_jsxs("div", { className: "border-border flex items-center justify-between border-b px-4 py-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "text-foreground truncate text-sm font-medium", children: section.name }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Managed outside the editor" })] }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close inspector", className: "text-muted-foreground hover:text-foreground hover:bg-accent rounded p-1", children: _jsx(X, { className: "h-4 w-4", "aria-hidden": true }) })] }), _jsx("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: _jsxs("div", { className: "border-border bg-muted text-muted-foreground space-y-2 rounded-md border p-3 text-sm", children: [_jsxs("p", { className: "text-foreground flex items-center gap-2 font-medium", children: [_jsx(Lock, { size: 14, "aria-hidden": true }), " Read-only section"] }), _jsxs("p", { children: ["The section type", ' ', _jsx("code", { className: "bg-background rounded px-1 py-0.5 text-xs", children: section.sectionType }), ' ', "isn't registered in this CMS, so it can't be edited here. It is preserved exactly as-is on every save."] }), _jsxs("p", { children: ["Edit it in your seed script or code, or register it via", ' ', _jsx("code", { className: "bg-background rounded px-1 py-0.5 text-xs", children: "sections.types" }), " in your config to make it editable."] })] }) })] }));
    }
    return (_jsxs("aside", { role: "dialog", "aria-label": `Edit ${section.name}`, className: "bg-card border-border flex h-full w-80 shrink-0 flex-col border-l", children: [_jsxs("div", { className: "border-border flex items-center justify-between border-b px-4 py-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "text-foreground truncate text-sm font-medium", children: section.name }), _jsx("p", { className: "text-muted-foreground text-xs", children: def?.name ?? 'Section' })] }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close inspector", className: "text-muted-foreground hover:text-foreground hover:bg-accent rounded p-1", children: _jsx(X, { className: "h-4 w-4", "aria-hidden": true }) })] }), _jsxs("div", { className: "flex-1 space-y-6 overflow-y-auto p-4", children: [!canEdit && (_jsx("p", { className: "border-border bg-muted text-muted-foreground rounded-md border p-2 text-xs", children: "You have read-only access to this page." })), _jsxs("fieldset", { disabled: !canEdit, className: "space-y-3", children: [_jsx("legend", { className: "text-muted-foreground mb-2 text-[10px] font-semibold tracking-wider uppercase", children: "Content" }), def?.fields.map((field) => (_jsx(ContentField, { field: field, value: section.content[field.key], onChange: (v) => onContentChange({ [field.key]: v }) }, field.key)))] }), _jsxs("fieldset", { disabled: !canEdit, className: "space-y-3", children: [_jsx("legend", { className: "text-muted-foreground mb-2 text-[10px] font-semibold tracking-wider uppercase", children: "Section settings" }), _jsxs("div", { children: [_jsx("label", { className: LABEL, htmlFor: "insp-name", children: "Section name" }), _jsx("input", { id: "insp-name", className: INPUT, value: section.name, onChange: (e) => onMetaChange({ name: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL, htmlFor: "insp-internal", children: "Internal label" }), _jsx("input", { id: "insp-internal", className: INPUT, placeholder: "Team-only note (optional)", value: section.internalLabel ?? '', onChange: (e) => onMetaChange({ internalLabel: e.target.value }) })] }), _jsxs("button", { type: "button", onClick: onToggleVisibility, disabled: !canEdit, "aria-pressed": !section.visible, className: "border-border text-foreground hover:bg-accent flex w-full items-center justify-between rounded-md border px-2.5 py-1.5 text-sm disabled:opacity-50", children: [_jsxs("span", { className: "flex items-center gap-2", children: [section.visible ? (_jsx(Eye, { className: "h-4 w-4", "aria-hidden": true })) : (_jsx(EyeOff, { className: "h-4 w-4", "aria-hidden": true })), section.visible ? 'Visible on page' : 'Hidden from page'] }), _jsx("span", { className: "text-muted-foreground text-xs", children: section.visible ? 'Hide' : 'Show' })] })] }), _jsxs("fieldset", { disabled: !canEdit, className: "space-y-3", children: [_jsx("legend", { className: "text-muted-foreground mb-2 text-[10px] font-semibold tracking-wider uppercase", children: "Appearance" }), _jsxs("div", { children: [_jsx("label", { className: LABEL, htmlFor: "insp-bg", children: "Background" }), _jsxs("select", { id: "insp-bg", className: INPUT, value: section.settings.backgroundType ?? 'none', onChange: (e) => onSettingsChange({
                                            backgroundType: e.target.value,
                                        }), children: [_jsx("option", { value: "none", children: "White" }), _jsx("option", { value: "solid", children: "Solid color" }), _jsx("option", { value: "gradient", children: "Gradient" })] })] }), section.settings.backgroundType && section.settings.backgroundType !== 'none' && (_jsxs("div", { children: [_jsx("label", { className: LABEL, htmlFor: "insp-bgcolor", children: "Color" }), _jsxs("select", { id: "insp-bgcolor", className: INPUT, value: section.settings.backgroundColor ?? 'purple', onChange: (e) => onSettingsChange({ backgroundColor: e.target.value }), children: [_jsx("option", { value: "purple", children: "Purple" }), _jsx("option", { value: "muted", children: "Light gray" })] })] })), _jsxs("div", { children: [_jsx("label", { className: LABEL, htmlFor: "insp-pad", children: "Spacing" }), _jsxs("select", { id: "insp-pad", className: INPUT, value: section.settings.paddingY ?? 'lg', onChange: (e) => onSettingsChange({ paddingY: e.target.value }), children: [_jsx("option", { value: "sm", children: "Small" }), _jsx("option", { value: "md", children: "Medium" }), _jsx("option", { value: "lg", children: "Large" }), _jsx("option", { value: "xl", children: "Extra large" })] })] })] }), _jsxs("fieldset", { disabled: !canEdit, className: "space-y-3", children: [_jsx("legend", { className: "text-muted-foreground mb-2 text-[10px] font-semibold tracking-wider uppercase", children: "Advanced" }), _jsxs("div", { children: [_jsx("label", { className: LABEL, htmlFor: "insp-anchor", children: "Anchor ID" }), _jsx("input", { id: "insp-anchor", className: INPUT, placeholder: "e.g. features", value: section.settings.anchorId ?? '', onChange: (e) => onSettingsChange({ anchorId: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL, htmlFor: "insp-css", children: "CSS class" }), _jsx("input", { id: "insp-css", className: INPUT, placeholder: "custom-class", value: section.settings.cssClass ?? '', onChange: (e) => onSettingsChange({ cssClass: e.target.value }) })] })] })] })] }));
}
// ─── Field renderers ─────────────────────────────────────────────────
function ContentField({ field, value, onChange, id: idProp, }) {
    const id = idProp ?? `insp-field-${field.key}`;
    const text = typeof value === 'string' ? value : '';
    const repeater = resolveRepeaterField(field);
    if (repeater) {
        return (_jsx(RepeaterField, { fieldKey: field.key, label: field.label, repeater: repeater, value: value, onChange: onChange }));
    }
    if (field.type === 'boolean') {
        return _jsx(BooleanField, { id: id, field: field, value: value === true, onChange: onChange });
    }
    if (field.type === 'relationship') {
        return _jsx(RelationshipField, { id: id, field: field, value: value, onChange: onChange });
    }
    if (field.type === 'media') {
        return _jsx(MediaField, { id: id, field: field, value: text, onChange: onChange });
    }
    if (field.type === 'select') {
        return (_jsxs("div", { children: [_jsx("label", { className: LABEL, htmlFor: id, children: field.label }), _jsx("select", { id: id, className: INPUT, value: text, onChange: (e) => onChange(e.target.value), children: field.options?.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) })] }));
    }
    if (field.type === 'textarea' || field.type === 'richText') {
        return (_jsxs("div", { children: [_jsxs("label", { className: LABEL, htmlFor: id, children: [field.label, field.required && _jsx("span", { className: "text-destructive ml-0.5", children: "*" })] }), _jsx("textarea", { id: id, className: `${INPUT} resize-y ${field.type === 'richText' ? 'min-h-[140px]' : 'min-h-[72px]'}`, value: text, placeholder: field.placeholder, onChange: (e) => onChange(e.target.value) }), field.help && _jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: field.help })] }));
    }
    return (_jsxs("div", { children: [_jsxs("label", { className: LABEL, htmlFor: id, children: [field.label, field.required && _jsx("span", { className: "text-destructive ml-0.5", children: "*" })] }), _jsx("input", { id: id, type: field.type === 'url' ? 'url' : 'text', className: INPUT, value: text, placeholder: field.placeholder, onChange: (e) => onChange(e.target.value) }), field.help && _jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: field.help })] }));
}
function MediaField({ id, field, value, onChange, }) {
    const [open, setOpen] = useState(false);
    return (_jsxs("div", { children: [_jsx("label", { className: LABEL, htmlFor: id, children: field.label }), _jsxs("div", { className: "flex gap-2", children: [_jsx("input", { id: id, className: `${INPUT} flex-1`, placeholder: "https://\u2026", value: value, onChange: (e) => onChange(e.target.value) }), _jsx("button", { type: "button", onClick: () => setOpen(true), className: "bg-accent text-foreground border-border hover:bg-accent/80 rounded-md border px-3 py-1.5 text-xs font-medium", children: "Browse" })] }), value && (_jsx("div", { className: "border-border bg-muted mt-2 overflow-hidden rounded-md border", children: _jsx("img", { src: value, alt: "", className: "h-28 w-full object-contain" }) })), _jsx(MediaPickerModal, { open: open, onClose: () => setOpen(false), onSelect: (url) => {
                    onChange(url);
                    setOpen(false);
                }, accept: "image/*" })] }));
}
function BooleanField({ id, field, value, onChange, }) {
    return (_jsxs("div", { children: [_jsxs("button", { type: "button", id: id, role: "switch", "aria-checked": value, onClick: () => onChange(!value), className: "border-border text-foreground hover:bg-accent flex w-full items-center justify-between rounded-md border px-2.5 py-1.5 text-sm", children: [_jsx("span", { children: field.label }), _jsx("span", { "aria-hidden": true, className: `relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors ${value ? 'bg-primary' : 'bg-muted'}`, children: _jsx("span", { className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${value ? 'translate-x-4' : 'translate-x-0.5'}` }) })] }), field.help && _jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: field.help })] }));
}
function RelationshipField({ id, field, value, onChange, }) {
    // Stored as an array of slugs; edited as a newline/comma-separated list
    // so authors can hand-pick referenced documents without a live picker.
    const slugs = Array.isArray(value) ? value : [];
    const text = slugs.join('\n');
    return (_jsxs("div", { children: [_jsx("label", { className: LABEL, htmlFor: id, children: field.label }), _jsx("textarea", { id: id, className: `${INPUT} min-h-[72px] resize-y`, placeholder: "one-slug-per-line", value: text, onChange: (e) => onChange(e.target.value
                    .split(/[\n,]/)
                    .map((s) => s.trim())
                    .filter(Boolean)) }), field.help && _jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: field.help })] }));
}
/**
 * Generic repeater editor: an orderable list of rows, each row a small form of
 * the repeater's sub-fields. Drives the generic `repeater` field type and the
 * `stats` / `gallery` shorthands (resolved upstream to the same row model), so
 * there's one editor for every structured-array field.
 *
 * Rows are stored as a plain array on `content[fieldKey]`. Drag/reorder uses an
 * index-derived row id (`row-0`, `row-1`, …); since every edit commits a fresh
 * array this stays consistent and matches the prior stats/gallery behavior.
 */
function RepeaterField({ fieldKey, label, repeater, value, onChange, }) {
    const rows = Array.isArray(value) ? value : [];
    const atCap = typeof repeater.maxRows === 'number' && rows.length >= repeater.maxRows;
    const rowKey = (i) => `row-${i}`;
    const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));
    function commit(next) {
        onChange(next);
    }
    function update(index, patch) {
        commit(rows.map((r, i) => (i === index ? { ...r, ...patch } : r)));
    }
    function remove(index) {
        commit(rows.filter((_, i) => i !== index));
    }
    function add() {
        if (atCap)
            return;
        commit([...rows, blankRepeaterRow(repeater.fields)]);
    }
    function handleDragEnd(event) {
        const { active, over } = event;
        if (!over || active.id === over.id)
            return;
        // Map the dnd id (index-derived rowKey) back to array positions.
        const ids = rows.map((_, i) => rowKey(i));
        const from = ids.indexOf(String(active.id));
        const to = ids.indexOf(String(over.id));
        if (from === -1 || to === -1)
            return;
        const next = rows.slice();
        const [moved] = next.splice(from, 1);
        next.splice(to, 0, moved);
        commit(next);
    }
    const lower = repeater.rowLabel.toLowerCase();
    return (_jsxs("div", { children: [_jsx("span", { className: LABEL, children: label }), rows.length === 0 ? (_jsxs("p", { className: "border-border text-muted-foreground mb-2 rounded-md border border-dashed px-2 py-3 text-center text-xs", children: ["No ", lower, "s yet."] })) : (_jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: rows.map((_, i) => rowKey(i)), strategy: verticalListSortingStrategy, children: _jsx("div", { className: "space-y-3", children: rows.map((row, i) => (_jsx(SortableRepeaterRow, { id: rowKey(i), index: i, fieldKey: fieldKey, rowLabel: repeater.rowLabel, fields: repeater.fields, row: row, reorderable: rows.length > 1, onPatch: (patch) => update(i, patch), onRemove: () => remove(i) }, rowKey(i)))) }) }) })), _jsxs("button", { type: "button", onClick: add, disabled: atCap, className: "border-border text-foreground hover:bg-accent mt-2 flex w-full items-center justify-center gap-1.5 rounded-md border border-dashed px-2 py-1.5 text-xs font-medium disabled:cursor-not-allowed disabled:opacity-50", children: [_jsx(Plus, { className: "h-3.5 w-3.5", "aria-hidden": true }), "Add ", lower] }), atCap && (_jsxs("p", { className: "text-muted-foreground mt-1 text-xs", children: ["Maximum of ", repeater.maxRows, " reached."] }))] }));
}
function SortableRepeaterRow({ id, index, fieldKey, rowLabel, fields, row, reorderable, onPatch, onRemove, }) {
    const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
        id,
        disabled: !reorderable,
    });
    const style = {
        transform: CSS.Transform.toString(transform),
        transition,
        zIndex: isDragging ? 10 : undefined,
    };
    return (_jsxs("div", { ref: setNodeRef, style: style, className: `border-border rounded-md border p-2 ${isDragging ? 'bg-card shadow-md' : ''}`, children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsxs("span", { className: "flex items-center gap-1", children: [reorderable && (_jsx("button", { type: "button", "aria-label": `Drag to reorder ${rowLabel} ${index + 1}`, className: "text-muted-foreground hover:text-foreground cursor-grab touch-none", ...attributes, ...listeners, children: _jsx(GripVertical, { className: "h-3.5 w-3.5", "aria-hidden": true }) })), _jsxs("span", { className: "text-muted-foreground text-xs", children: [rowLabel, " ", index + 1] })] }), _jsx("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${rowLabel.toLowerCase()} ${index + 1}`, className: "text-muted-foreground hover:text-destructive rounded p-0.5", children: _jsx(X, { className: "h-3.5 w-3.5", "aria-hidden": true }) })] }), _jsx("div", { className: "space-y-2", children: fields.map((sub) => (_jsx(ContentField, { id: `insp-${fieldKey}-${index}-${sub.key}`, field: sub, value: row[sub.key], onChange: (v) => onPatch({ [sub.key]: v }) }, sub.key))) })] }));
}
//# sourceMappingURL=SectionInspector.js.map