'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useState } from 'react';
import { AlertTriangle, ArrowLeft, Layout, Loader2, Save } from 'lucide-react';
import { toast } from 'sonner';
import { ConfirmDialog } from '../../components/ui/ConfirmDialog.js';
import { ErrorBoundary } from '../../components/ErrorBoundary.js';
import { addSection, createSection, duplicateSection, fetchTemplateForEditor, reorderSections, removeSection, saveTemplate, toggleSectionVisibility, updateSectionContent, updateSectionMeta, updateSectionSettings, validateTemplate, } from '../../lib/post-editor-service.js';
import { DEFAULT_VIEWPORT } from '../page-editor/viewports.js';
import { SectionsPanel } from '../page-editor/SectionsPanel.js';
import { SectionInspector } from '../page-editor/SectionInspector.js';
import { AddSectionModal } from '../page-editor/AddSectionModal.js';
import { PostEditorCanvas } from './PostEditorCanvas.js';
import { PostHeaderPanel } from './PostHeaderPanel.js';
function deriveCanEdit(session) {
    const role = session?.user?.role;
    if (!role)
        return true;
    return ['ADMIN', 'EDITOR'].includes(role);
}
const SAMPLE_CONTEXT = {
    title: 'Sample Post Title',
    excerpt: 'A short summary that previews how the header excerpt will look.',
    body: 'This is sample body copy.\n\nIt shows how the Article Body section renders the post body once an author writes a post with this template.',
    publishDate: new Date().toISOString(),
    category: 'Category',
    author: { name: 'Author Name', bio: 'A short example author bio for the preview.' },
};
export function PostTemplateEditor({ postType, config, session, onNavigate, }) {
    const [template, setTemplate] = useState(null);
    const [loading, setLoading] = useState(true);
    const [loadError, setLoadError] = useState(null);
    // selection: a section id, the special 'header' panel, or nothing.
    const [selected, setSelected] = useState(null);
    const [viewport, setViewport] = useState(DEFAULT_VIEWPORT);
    const [dirty, setDirty] = useState(false);
    const [saving, setSaving] = useState(false);
    const [addOpen, setAddOpen] = useState(false);
    const [deleteTargetId, setDeleteTargetId] = useState(null);
    const [leaveTarget, setLeaveTarget] = useState(null);
    const canEdit = useMemo(() => deriveCanEdit(session), [session]);
    const typeLabel = useMemo(() => {
        const col = config?.collections?.[postType];
        return col?.labels?.singular ?? postType;
    }, [config, postType]);
    useEffect(() => {
        let cancelled = false;
        setLoading(true);
        setLoadError(null);
        fetchTemplateForEditor(postType)
            .then((t) => {
            if (!cancelled)
                setTemplate(t);
        })
            .catch((err) => {
            if (!cancelled)
                setLoadError(err instanceof Error ? err.message : 'Failed to load template');
        })
            .finally(() => {
            if (!cancelled)
                setLoading(false);
        });
        return () => {
            cancelled = true;
        };
    }, [postType]);
    useEffect(() => {
        if (!dirty)
            return;
        function onBeforeUnload(e) {
            e.preventDefault();
            e.returnValue = '';
        }
        window.addEventListener('beforeunload', onBeforeUnload);
        return () => window.removeEventListener('beforeunload', onBeforeUnload);
    }, [dirty]);
    const mutateSections = useCallback((fn) => {
        setTemplate((prev) => (prev ? { ...prev, sections: fn(prev.sections) } : prev));
        setDirty(true);
    }, []);
    const handleHeaderChange = useCallback((patch) => {
        setTemplate((prev) => (prev ? { ...prev, header: { ...prev.header, ...patch } } : prev));
        setDirty(true);
    }, []);
    const handleAdd = useCallback((type) => {
        const section = createSection(type);
        mutateSections((s) => addSection(s, section));
        setSelected({ kind: 'section', id: section.id });
        setAddOpen(false);
    }, [mutateSections]);
    const selectedSectionId = selected?.kind === 'section' ? selected.id : null;
    const handleSave = useCallback(async () => {
        if (!template)
            return;
        const result = validateTemplate(template);
        if (result.errors.length > 0) {
            toast.error(result.errors[0]);
            return;
        }
        setSaving(true);
        try {
            const saved = await saveTemplate(template);
            setTemplate(saved);
            setDirty(false);
            toast.success('Template saved');
        }
        catch (err) {
            toast.error(err instanceof Error ? err.message : 'Failed to save template');
        }
        finally {
            setSaving(false);
        }
    }, [template]);
    const guardedNavigate = useCallback((path) => {
        if (dirty)
            setLeaveTarget(path);
        else
            onNavigate(path);
    }, [dirty, onNavigate]);
    if (loading) {
        return (_jsxs("div", { className: "bg-background flex h-full items-center justify-center", children: [_jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin", "aria-hidden": true }), _jsx("span", { className: "sr-only", children: "Loading template editor\u2026" })] }));
    }
    if (loadError || !template) {
        return (_jsx("div", { className: "bg-background flex h-full items-center justify-center p-6", children: _jsxs("div", { className: "border-destructive/30 bg-destructive/5 flex max-w-md items-center gap-3 rounded-lg border p-4", children: [_jsx(AlertTriangle, { className: "text-destructive shrink-0", size: 20, "aria-hidden": true }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-foreground text-sm font-medium", children: "Failed to load template" }), _jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: loadError ?? 'Not found.' }), _jsx("button", { type: "button", onClick: () => onNavigate('/posts/types'), className: "text-primary mt-2 text-sm font-medium hover:underline", children: "Back to Post Types" })] })] }) }));
    }
    const selectedSection = template.sections.find((s) => s.id === selectedSectionId) ?? null;
    return (_jsxs(ErrorBoundary, { children: [_jsxs("div", { className: "bg-background flex h-full flex-col overflow-hidden", children: [_jsxs("header", { className: "bg-card border-border flex h-14 shrink-0 items-center justify-between gap-4 border-b px-4", children: [_jsxs("nav", { "aria-label": "Breadcrumb", className: "flex min-w-0 items-center gap-1.5 text-sm", children: [_jsxs("button", { type: "button", onClick: () => guardedNavigate('/posts/types'), className: "text-muted-foreground hover:text-foreground inline-flex shrink-0 items-center gap-1.5", children: [_jsx(ArrowLeft, { className: "h-4 w-4", "aria-hidden": true }), "Post Types"] }), _jsx("span", { className: "text-muted-foreground", "aria-hidden": true, children: "/" }), _jsxs("span", { className: "text-foreground truncate font-medium", children: [typeLabel, " Template"] }), dirty && (_jsx("span", { className: "text-muted-foreground ml-2 text-xs", "aria-live": "polite", children: "Unsaved changes" }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { type: "button", onClick: () => setSelected({ kind: 'header' }), className: `inline-flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors ${selected?.kind === 'header'
                                            ? 'border-primary bg-accent text-foreground'
                                            : 'border-border text-foreground hover:bg-accent'}`, children: [_jsx(Layout, { className: "h-4 w-4", "aria-hidden": true }), "Header"] }), _jsxs("button", { type: "button", onClick: handleSave, disabled: !canEdit || saving || !dirty, className: "bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 rounded-lg px-3.5 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50", children: [saving ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin", "aria-hidden": true })) : (_jsx(Save, { className: "h-3.5 w-3.5", "aria-hidden": true })), "Save"] })] })] }), _jsxs("div", { className: "flex flex-1 overflow-hidden", children: [_jsx(SectionsPanel, { sections: template.sections, selectedId: selectedSectionId, canEdit: canEdit, onSelect: (id) => setSelected({ kind: 'section', id }), onReorder: (ids) => mutateSections((s) => reorderSections(s, ids)), onToggleVisibility: (id) => mutateSections((s) => toggleSectionVisibility(s, id)), onDuplicate: (id) => mutateSections((s) => duplicateSection(s, id)), onRequestDelete: (id) => setDeleteTargetId(id), onAdd: () => setAddOpen(true) }), _jsx("div", { className: "flex-1 overflow-hidden", children: _jsx(PostEditorCanvas, { sections: template.sections, header: template.header, context: SAMPLE_CONTEXT, selectedId: selectedSectionId, viewport: viewport, onSelect: (id) => setSelected({ kind: 'section', id }), onAddSection: () => setAddOpen(true) }) }), selected?.kind === 'header' && (_jsx(PostHeaderPanel, { header: template.header, canEdit: canEdit, onClose: () => setSelected(null), onChange: handleHeaderChange })), selectedSection && (_jsx(SectionInspector, { section: selectedSection, canEdit: canEdit, onClose: () => setSelected(null), onContentChange: (patch) => mutateSections((s) => updateSectionContent(s, selectedSection.id, patch)), onSettingsChange: (patch) => mutateSections((s) => updateSectionSettings(s, selectedSection.id, patch)), onMetaChange: (patch) => mutateSections((s) => updateSectionMeta(s, selectedSection.id, patch)), onToggleVisibility: () => mutateSections((s) => toggleSectionVisibility(s, selectedSection.id)) }))] })] }), _jsx(AddSectionModal, { open: addOpen, scope: "post", onClose: () => setAddOpen(false), onAdd: handleAdd }), _jsx(ConfirmDialog, { open: deleteTargetId !== null, onClose: () => setDeleteTargetId(null), onConfirm: () => {
                    if (deleteTargetId) {
                        mutateSections((s) => removeSection(s, deleteTargetId));
                        if (selectedSectionId === deleteTargetId)
                            setSelected(null);
                    }
                    setDeleteTargetId(null);
                }, title: "Delete section?", description: "This removes the section from the template. You can undo by leaving without saving.", confirmLabel: "Delete", destructive: true }), _jsx(ConfirmDialog, { open: leaveTarget !== null, onClose: () => setLeaveTarget(null), onConfirm: () => {
                    const target = leaveTarget;
                    setLeaveTarget(null);
                    setDirty(false);
                    if (target)
                        onNavigate(target);
                }, title: "Discard unsaved changes?", description: "You have unsaved changes that will be lost if you leave now.", confirmLabel: "Leave", cancelLabel: "Stay", destructive: true })] }));
}
//# sourceMappingURL=PostTemplateEditor.js.map