'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useMemo, useState } from 'react';
import { AlertTriangle, Copy, FilePlus, Layers, Pencil, RefreshCw, Trash2 } from 'lucide-react';
import { toast } from 'sonner';
import { cmsApi } from '../../lib/api.js';
import { useApiData } from '../../lib/useApiData.js';
import { ConfirmDialog } from '../../components/ui/ConfirmDialog.js';
import { EmptyState } from '../../components/ui/EmptyState.js';
import { FilterPill } from '../../components/ui/FilterPill.js';
import { Input } from '../../components/ui/Input.js';
import { Modal } from '../../components/ui/Modal.js';
import { Button } from '../../components/ui/Button.js';
import { RowActions, RowActionButton } from '../../components/ui/RowActions.js';
import { SearchInput } from '../../components/ui/SearchInput.js';
import { Select } from '../../components/ui/Select.js';
import { Skeleton } from '../../components/ui/Skeleton.js';
const CATEGORIES = {
    content: { label: 'Content', dot: 'bg-[var(--acc)]', text: 'text-[var(--acc)]' },
    landing: { label: 'Landing', dot: 'bg-[var(--suc)]', text: 'text-[var(--suc)]' },
    utility: { label: 'Utility', dot: 'bg-[var(--warn)]', text: 'text-[var(--warn)]' },
};
function categoryOf(template) {
    const cat = template.category;
    return cat === 'landing' || cat === 'utility' ? cat : 'content';
}
function sectionCountOf(template) {
    return Array.isArray(template.tree?.children) ? template.tree.children.length : 0;
}
export function PageTemplates({ onNavigate }) {
    const { data, loading, error, refetch } = useApiData('/page-templates');
    const templates = useMemo(() => data ?? [], [data]);
    const [search, setSearch] = useState('');
    const [category, setCategory] = useState('all');
    const [editTarget, setEditTarget] = useState(null);
    const [deleteTarget, setDeleteTarget] = useState(null);
    const filtered = useMemo(() => {
        const q = search.trim().toLowerCase();
        return templates.filter((t) => {
            const matchesQuery = !q ||
                (t.name ?? '').toLowerCase().includes(q) ||
                (t.description ?? '').toLowerCase().includes(q);
            const matchesCategory = category === 'all' || categoryOf(t) === category;
            return matchesQuery && matchesCategory;
        });
    }, [templates, search, category]);
    async function confirmDelete() {
        if (!deleteTarget)
            return;
        const res = await cmsApi(`/page-templates/${deleteTarget.id}`, { method: 'DELETE' });
        if (res.error) {
            toast.error(res.error);
        }
        else {
            toast.success('Template deleted');
            refetch();
        }
    }
    async function duplicateTemplate(template) {
        // The list payload carries the full tree, so no extra fetch is needed.
        // Duplicating a built-in is the supported way to customize one (built-ins
        // themselves are locked against edits).
        if (!template.tree) {
            toast.error('Template has no layout to duplicate');
            return;
        }
        const res = await cmsApi('/page-templates', {
            method: 'POST',
            body: JSON.stringify({
                name: `${template.name ?? 'Untitled template'} (copy)`,
                description: template.description ?? null,
                category: categoryOf(template),
                tree: template.tree,
                thumbnail: template.thumbnail ?? null,
            }),
        });
        if (res.error) {
            toast.error(res.error);
        }
        else {
            toast.success('Template duplicated');
            refetch();
        }
    }
    return (_jsxs("div", { className: "p-4 pr-8", children: [error && (_jsxs("div", { className: "mb-4 flex items-center gap-3 rounded-[var(--r)] border border-[var(--bdr)] bg-[var(--card)] p-3", children: [_jsx(AlertTriangle, { className: "h-5 w-5 shrink-0 text-[var(--muted)]", "aria-hidden": true }), _jsx("span", { className: "flex-1 text-sm text-[var(--txt)]", children: error }), _jsx("button", { type: "button", onClick: refetch, className: "rounded-md border border-[var(--bdr)] px-3 py-1 text-sm text-[var(--txt)] hover:bg-[var(--acc-l)]", children: "Retry" })] })), _jsxs("div", { className: "mb-4 flex items-center justify-between gap-4", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-foreground mb-1", children: "Page Templates" }), _jsxs("p", { className: "text-sm text-[var(--sub)]", children: [templates.length, " saved template", templates.length === 1 ? '' : 's'] })] }), _jsx(Button, { type: "button", variant: "outline", size: "md", onClick: refetch, leftIcon: _jsx(RefreshCw, { size: 16, "aria-hidden": true }), children: "Refresh" })] }), !loading && templates.length > 0 && (_jsxs("div", { className: "mb-4 flex flex-wrap items-center gap-2", children: [_jsx("div", { className: "max-w-xs min-w-52 flex-1", children: _jsx(SearchInput, { value: search, onChange: setSearch, placeholder: "Search templates\u2026" }) }), _jsxs("div", { className: "flex gap-1.5", role: "group", "aria-label": "Filter templates by category", children: [_jsx(FilterPill, { active: category === 'all', onClick: () => setCategory('all'), children: "All" }), Object.keys(CATEGORIES).map((cat) => (_jsx(FilterPill, { active: category === cat, onClick: () => setCategory(cat), children: CATEGORIES[cat].label }, cat)))] }), _jsxs("span", { className: "ml-auto text-[12.5px] whitespace-nowrap text-[var(--muted)]", children: [filtered.length, " of ", templates.length] })] })), loading ? (_jsx("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3", role: "status", "aria-live": "polite", "aria-label": "Loading page templates", children: Array.from({ length: 6 }, (_, i) => (_jsx(Skeleton, { variant: "card" }, i))) })) : templates.length === 0 ? (_jsx(EmptyState, { icon: _jsx(Layers, { size: 24, "aria-hidden": true }), title: "No page templates yet", description: "Built-in templates are seeded by the CMS when the templates API is available.", actionLabel: "View Saved Sections", onAction: () => onNavigate?.('/saved-sections') })) : filtered.length === 0 ? (_jsx("p", { className: "py-12 text-center text-sm text-[var(--muted)]", children: "No templates match your search." })) : (_jsx("ul", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3", "aria-label": "Page templates", children: filtered.map((template) => (_jsx(TemplateCard, { template: template, onUse: () => onNavigate?.(`/page-builder/new?template=${template.id}`), onDuplicate: () => void duplicateTemplate(template), onEdit: () => setEditTarget(template), onDelete: () => setDeleteTarget(template) }, template.id))) })), _jsx(TemplateEditModal, { template: editTarget, onClose: () => setEditTarget(null), onSaved: () => {
                    setEditTarget(null);
                    refetch();
                } }), _jsx(ConfirmDialog, { open: deleteTarget !== null, onClose: () => setDeleteTarget(null), onConfirm: () => void confirmDelete(), title: "Delete template?", description: `"${deleteTarget?.name ?? 'This template'}" will be permanently removed. Pages already created from it are not affected.`, confirmLabel: "Delete", destructive: true })] }));
}
function TemplateCard({ template, onUse, onDuplicate, onEdit, onDelete, }) {
    const cat = CATEGORIES[categoryOf(template)];
    const sections = sectionCountOf(template);
    const name = template.name ?? 'Untitled template';
    const updated = template.updatedAt ? new Date(template.updatedAt).toLocaleDateString() : null;
    return (_jsxs("li", { className: "group relative flex flex-col overflow-hidden rounded-[var(--r)] border border-[var(--bdr)] bg-[var(--card)] shadow-[var(--shd)] transition-[border-color,box-shadow,transform] duration-[var(--motion-fast)] focus-within:border-[var(--acc-m)] focus-within:shadow-[var(--shd2)] hover:-translate-y-0.5 hover:border-[var(--acc-m)] hover:shadow-[var(--shd2)] motion-reduce:hover:translate-y-0", children: [_jsx(TemplatePreview, { template: template, sections: sections }), _jsxs("div", { className: "flex flex-1 flex-col p-4 pb-0", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsx("h2", { className: "text-[15px] leading-snug font-medium text-[var(--txt)]", children: name }), template.builtIn && (_jsx("span", { className: "shrink-0 rounded-full border border-[var(--bdr)] bg-[var(--bg)] px-2 py-0.5 text-[10.5px] font-medium whitespace-nowrap text-[var(--sub)]", children: "Built-in" }))] }), _jsx("p", { className: "mt-2 min-h-10 text-[12.5px] leading-relaxed text-[var(--sub)]", children: template.description ?? 'No description provided.' }), _jsxs("div", { className: "relative mt-3 flex h-[46px] items-center justify-between border-t border-[var(--bdr)] py-2.5", children: [_jsxs("span", { className: `inline-flex items-center gap-1.5 text-[11.5px] font-medium ${cat.text}`, children: [_jsx("span", { "aria-hidden": true, className: `h-[7px] w-[7px] shrink-0 rounded-full ${cat.dot}` }), cat.label] }), _jsxs("span", { className: "text-[11.5px] text-[var(--muted)] transition-opacity duration-[var(--motion-fast)] group-focus-within:opacity-0 group-hover:opacity-0", children: [sections, " section", sections === 1 ? '' : 's', updated ? ` · ${updated}` : ''] }), _jsxs(RowActions, { className: "absolute top-1/2 right-0 -translate-y-1/2", children: [_jsx(RowActionButton, { "aria-label": `Create page from ${name}`, onClick: onUse, children: _jsx(FilePlus, { size: 14, "aria-hidden": true }) }), _jsx(RowActionButton, { "aria-label": `Duplicate ${name}`, onClick: onDuplicate, children: _jsx(Copy, { size: 14, "aria-hidden": true }) }), !template.builtIn && (_jsxs(_Fragment, { children: [_jsx(RowActionButton, { "aria-label": `Edit ${name}`, onClick: onEdit, children: _jsx(Pencil, { size: 14, "aria-hidden": true }) }), _jsx(RowActionButton, { "aria-label": `Delete ${name}`, danger: true, onClick: onDelete, children: _jsx(Trash2, { size: 14, "aria-hidden": true }) })] }))] })] })] })] }));
}
/**
 * Card preview area. Uses the stored thumbnail when one exists; otherwise
 * renders an honest wireframe placeholder built from the template's section
 * count (a hero band plus one bar per section) — no fake screenshots.
 */
function TemplatePreview({ template, sections }) {
    if (template.thumbnail) {
        return (_jsx("div", { className: "h-28 shrink-0 overflow-hidden border-b border-[var(--bdr)] bg-[var(--bg)]", children: _jsx("img", { src: template.thumbnail, alt: `Preview of ${template.name ?? 'template'}`, className: "h-full w-full object-cover" }) }));
    }
    const bars = Math.max(0, Math.min(sections - 1, 3));
    return (_jsxs("div", { "aria-hidden": true, className: "flex h-28 shrink-0 flex-col gap-1.5 border-b border-[var(--bdr)] bg-[var(--bg)] p-3", children: [_jsx("div", { className: "h-9 rounded-[5px] bg-[var(--acc-l)]" }), Array.from({ length: bars }, (_, i) => (_jsx("div", { className: "h-3.5 rounded-[4px] bg-[var(--bdr)]", style: { width: `${88 - i * 14}%` } }, i)))] }));
}
function TemplateEditModal({ template, onClose, onSaved, }) {
    // Keyed remount seeds the form state from the selected template each time
    // the modal opens, without effect-based state syncing.
    if (!template)
        return null;
    return (_jsx(TemplateEditForm, { template: template, onClose: onClose, onSaved: onSaved }, template.id));
}
function TemplateEditForm({ template, onClose, onSaved, }) {
    const [name, setName] = useState(template.name ?? '');
    const [description, setDescription] = useState(template.description ?? '');
    const [category, setCategory] = useState(categoryOf(template));
    const [saving, setSaving] = useState(false);
    async function handleSave() {
        if (!name.trim()) {
            toast.error('Template name is required');
            return;
        }
        setSaving(true);
        const res = await cmsApi(`/page-templates/${template.id}`, {
            method: 'PUT',
            body: JSON.stringify({
                name: name.trim(),
                description: description.trim() || null,
                category,
            }),
        });
        setSaving(false);
        if (res.error) {
            toast.error(res.error);
        }
        else {
            toast.success('Template updated');
            onSaved();
        }
    }
    return (_jsx(Modal, { open: true, onClose: onClose, title: "Edit template", actions: _jsxs(_Fragment, { children: [_jsx(Button, { variant: "ghost", onClick: onClose, disabled: saving, children: "Cancel" }), _jsx(Button, { variant: "primary", onClick: () => void handleSave(), loading: saving, children: "Save changes" })] }), children: _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("label", { className: "flex flex-col gap-1.5", children: [_jsx("span", { className: "text-sm font-medium text-[var(--txt)]", children: "Name" }), _jsx(Input, { value: name, onChange: (e) => setName(e.target.value), placeholder: "Template name" })] }), _jsxs("label", { className: "flex flex-col gap-1.5", children: [_jsx("span", { className: "text-sm font-medium text-[var(--txt)]", children: "Description" }), _jsx("textarea", { value: description, onChange: (e) => setDescription(e.target.value), rows: 3, placeholder: "What this template is for\u2026", className: "w-full resize-y rounded-[var(--r-control)] border border-[var(--bdr)] bg-[var(--input-background)] px-3 py-2 text-sm text-[var(--txt)] placeholder:text-[var(--muted)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none" })] }), _jsxs("label", { className: "flex flex-col gap-1.5", children: [_jsx("span", { className: "text-sm font-medium text-[var(--txt)]", children: "Category" }), _jsx(Select, { value: category, onChange: (e) => setCategory(e.target.value), children: Object.keys(CATEGORIES).map((cat) => (_jsx("option", { value: cat, children: CATEGORIES[cat].label }, cat))) })] })] }) }));
}
//# sourceMappingURL=PageTemplates.js.map