'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useEffect, useMemo, useState } from 'react';
import { Check, ChevronRight, Copy, ExternalLink, FileQuestion, LayoutTemplate, Lock, Plus, } from 'lucide-react';
import { toast } from 'sonner';
import { fetchPosts } from '../../lib/posts-service.js';
import { fetchPostTypeDetail, fieldKeyFromName, fieldTypeLabel, humanizeFieldName, renderFieldSnippet, } from '../../lib/post-types-service.js';
import { paletteFor } from '../../components/posts/badges.js';
import { resolvePostTypeIcon } from '../../components/posts/icons.js';
import { Toggle } from '../../components/ui/Toggle.js';
const ADDABLE_FIELD_TYPES = [
    { type: 'text', desc: 'Single line' },
    { type: 'richText', desc: 'WYSIWYG' },
    { type: 'number', desc: 'Int / decimal' },
    { type: 'date', desc: 'Date & time' },
    { type: 'boolean', desc: 'True / false' },
    { type: 'url', desc: 'Web address' },
    { type: 'email', desc: 'Email address' },
    { type: 'select', desc: 'Dropdown' },
    { type: 'media', desc: 'Image / file' },
    { type: 'relationship', desc: 'Link to type' },
    { type: 'json', desc: 'Raw data' },
];
export function PostTypeEditor({ slug, onNavigate }) {
    const [detail, setDetail] = useState(null);
    const [postCount, setPostCount] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    const [notFound, setNotFound] = useState(false);
    const [refreshToken, setRefreshToken] = useState(0);
    useEffect(() => {
        let cancelled = false;
        setLoading(true);
        setError(null);
        setNotFound(false);
        Promise.all([fetchPostTypeDetail(slug), fetchPosts({ pageSize: 1 }).catch(() => null)])
            .then(([d, postsRes]) => {
            if (cancelled)
                return;
            if (!d) {
                setNotFound(true);
            }
            else {
                setDetail(d);
                const typeRow = postsRes?.types.find((t) => t.slug === slug);
                setPostCount(typeRow?.postCount ?? null);
            }
            setLoading(false);
        })
            .catch((err) => {
            if (cancelled)
                return;
            setError(err instanceof Error ? err.message : 'Failed to load post type');
            setLoading(false);
        });
        return () => {
            cancelled = true;
        };
    }, [slug, refreshToken]);
    if (loading)
        return _jsx(EditorSkeleton, {});
    if (notFound) {
        return (_jsx(CenteredNotice, { title: `No post type named "${slug}"`, body: "It may have been removed from actuate.config.ts.", actionLabel: "Back to Post Types", onAction: () => onNavigate('/posts/types') }));
    }
    if (error || !detail) {
        return (_jsx(CenteredNotice, { title: error ?? 'Failed to load post type', actionLabel: "Try again", onAction: () => setRefreshToken((t) => t + 1) }));
    }
    return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsx(EditorToolbar, { detail: detail, postCount: postCount, onNavigate: onNavigate }), _jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-6 overflow-y-auto p-4 sm:p-6 lg:flex-row lg:items-start lg:overflow-hidden", children: [_jsx(IdentityPanel, { detail: detail }), _jsx(FieldBuilder, { detail: detail })] })] }));
}
// ─── Toolbar ─────────────────────────────────────────────────────────
function EditorToolbar({ detail, postCount, onNavigate, }) {
    const palette = paletteFor(detail.color);
    return (_jsxs("div", { className: "border-border bg-card flex flex-wrap items-center gap-3 border-b px-6 py-4 sm:px-6", children: [_jsxs("nav", { "aria-label": "Breadcrumb", className: "flex min-w-0 items-center gap-1.5 text-sm", children: [_jsx("button", { type: "button", onClick: () => onNavigate('/posts/types'), className: "text-muted-foreground hover:text-foreground transition-colors", children: "Post Types" }), _jsx(ChevronRight, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0", "aria-hidden": true }), _jsx("span", { className: "text-foreground truncate font-medium", children: detail.plural })] }), postCount !== null && (_jsxs("span", { className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium tabular-nums ${palette.bg} ${palette.text}`, children: [postCount, " ", postCount === 1 ? 'post' : 'posts'] })), _jsxs("div", { className: "ml-auto flex items-center gap-2", children: [_jsxs("button", { type: "button", onClick: () => onNavigate(`/posts/types/${detail.slug}/template`), className: "border-border text-foreground hover:bg-accent focus-visible:ring-ring inline-flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors focus:outline-none focus-visible:ring-2", children: [_jsx(LayoutTemplate, { className: "h-3.5 w-3.5", "aria-hidden": true }), "Edit template"] }), _jsxs("button", { type: "button", onClick: () => onNavigate('/posts'), className: "bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:ring-ring inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium shadow-sm transition-colors focus:outline-none focus-visible:ring-2", children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5", "aria-hidden": true }), "View posts"] })] })] }));
}
// ─── Identity panel (left, 340px) ────────────────────────────────────
function IdentityPanel({ detail }) {
    const palette = paletteFor(detail.color);
    const Icon = resolvePostTypeIcon(detail.icon);
    return (_jsxs("aside", { "aria-label": "Post type identity", className: "flex w-full shrink-0 flex-col gap-5 lg:max-h-full lg:w-[340px] lg:overflow-y-auto", children: [_jsxs(IdentitySection, { title: "Identity", children: [_jsx(ReadOnlyField, { label: "Type Name", value: detail.plural }), _jsx(ReadOnlyField, { label: "API Slug", value: detail.slug, mono: true }), _jsx(ReadOnlyField, { label: "Description", value: detail.description ?? 'No description provided.' }), _jsxs("p", { className: "text-muted-foreground text-xs", children: ["Identity and fields are defined in ", _jsx("code", { className: "font-mono", children: "actuate.config.ts" }), ' ', "under ", _jsxs("code", { className: "font-mono", children: ["collections.", detail.slug] }), ". Edit the config and redeploy to change them."] })] }), _jsx(IdentitySection, { title: "Icon & color", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: `inline-flex h-10 w-10 items-center justify-center rounded-lg ${palette.bg} ${palette.text}`, children: _jsx(Icon, { className: "h-5 w-5", "aria-hidden": true }) }), _jsxs("div", { className: "flex flex-col gap-0.5 text-sm", children: [_jsx("span", { className: "text-foreground font-medium", children: detail.icon ?? 'file-text' }), _jsxs("span", { className: "text-muted-foreground text-xs", children: ["Accent: ", detail.color ?? 'default'] })] })] }) }), _jsx(IdentitySection, { title: "API preview", children: _jsxs("div", { className: "border-border bg-muted flex flex-col gap-1.5 overflow-x-auto rounded-lg border p-3 font-mono text-xs", children: [_jsx(ApiRow, { method: "GET", path: `/api/cms/collections/${detail.slug}` }), _jsx(ApiRow, { method: "GET", path: `/api/cms/collections/${detail.slug}/{id}` }), _jsx(ApiRow, { method: "POST", path: `/api/cms/collections/${detail.slug}` })] }) })] }));
}
function IdentitySection({ title, children }) {
    return (_jsxs("section", { className: "bg-card border-border flex flex-col gap-3 rounded-xl border p-5 shadow-sm", children: [_jsx("h2", { className: "text-muted-foreground text-xs font-medium tracking-wide uppercase", children: title }), children] }));
}
function ReadOnlyField({ label, value, mono }) {
    return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-foreground text-sm font-medium", children: label }), _jsx("div", { className: `border-border bg-muted text-foreground rounded-lg border px-3 py-1.5 text-sm ${mono ? 'font-mono' : ''}`, children: value })] }));
}
function ApiRow({ method, path }) {
    return (_jsxs("div", { className: "flex items-center gap-2 whitespace-nowrap", children: [_jsx("span", { className: `w-10 shrink-0 font-medium ${method === 'GET' ? 'text-success' : 'text-info'}`, children: method }), _jsx("span", { className: "text-muted-foreground", children: path })] }));
}
// ─── Field builder (right) ───────────────────────────────────────────
function FieldBuilder({ detail }) {
    return (_jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-4 lg:max-h-full lg:overflow-y-auto", children: [_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("h2", { className: "text-foreground text-base font-medium", children: "Field Builder" }), _jsxs("p", { className: "text-muted-foreground text-sm", children: [detail.fields.length, " ", detail.fields.length === 1 ? 'field' : 'fields', " defined in", ' ', _jsx("code", { className: "font-mono", children: "actuate.config.ts" })] })] }), _jsx(FieldList, { detail: detail }), _jsx(AddFieldCard, { detail: detail })] }));
}
function FieldList({ detail }) {
    return (_jsxs("div", { className: "bg-card border-border rounded-xl border shadow-sm", children: [_jsxs("div", { className: "border-border flex items-center gap-2 border-b px-6 py-4", children: [_jsx(Lock, { className: "text-muted-foreground h-3.5 w-3.5", "aria-hidden": true }), _jsx("span", { className: "text-foreground text-sm font-medium", children: "Fields" }), _jsxs("span", { className: "bg-muted text-muted-foreground ml-auto rounded-full px-2 py-0.5 text-xs font-medium", children: ["Defined in code \u00B7 ", detail.fields.length, " ", detail.fields.length === 1 ? 'field' : 'fields'] })] }), detail.fields.length === 0 ? (_jsx("p", { className: "text-muted-foreground px-4 py-6 text-center text-sm", children: "This type has no fields yet. Add one below." })) : (_jsx("ul", { className: "divide-border divide-y", children: detail.fields.map((f) => (_jsxs("li", { className: "flex items-center gap-3 px-4 py-2.5", children: [_jsx(Lock, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0", "aria-hidden": true }), _jsxs("div", { className: "flex min-w-0 flex-col", children: [_jsx("span", { className: "text-foreground truncate text-sm font-medium", children: humanizeFieldName(f.name) }), _jsx("span", { className: "text-muted-foreground truncate font-mono text-xs", children: f.name })] }), _jsx("span", { className: "border-border text-muted-foreground ml-auto shrink-0 rounded-full border px-2 py-0.5 text-xs", children: fieldTypeLabel(f.type) }), _jsx("span", { className: `shrink-0 rounded-full px-2 py-0.5 text-xs font-medium ${f.required
                                ? 'bg-destructive/10 text-destructive'
                                : 'bg-muted text-muted-foreground'}`, children: f.required ? 'Required' : 'Optional' })] }, f.name))) }))] }));
}
// ─── Add Field (snippet generator) ───────────────────────────────────
function AddFieldCard({ detail }) {
    const [open, setOpen] = useState(false);
    const [fieldType, setFieldType] = useState(null);
    const [name, setName] = useState('');
    const [helpText, setHelpText] = useState('');
    const [required, setRequired] = useState(false);
    const [copied, setCopied] = useState(false);
    const key = useMemo(() => fieldKeyFromName(name), [name]);
    const existingKeys = useMemo(() => new Set(detail.fields.map((f) => f.name)), [detail.fields]);
    const duplicate = key !== '' && existingKeys.has(key);
    const snippet = useMemo(() => {
        if (!fieldType || !key)
            return '';
        return renderFieldSnippet({
            key,
            label: name.trim() || humanizeFieldName(key),
            type: fieldType,
            required,
            helpText,
        });
    }, [fieldType, key, name, required, helpText]);
    const reset = () => {
        setFieldType(null);
        setName('');
        setHelpText('');
        setRequired(false);
        setCopied(false);
    };
    const copy = async () => {
        try {
            await navigator.clipboard.writeText(snippet);
            setCopied(true);
            toast.success('Field snippet copied — paste it into the fields map');
            setTimeout(() => setCopied(false), 1800);
        }
        catch {
            toast.error('Copy failed — select the snippet manually');
        }
    };
    if (!open) {
        return (_jsxs("button", { type: "button", onClick: () => setOpen(true), className: "border-border text-muted-foreground hover:text-foreground hover:border-primary/50 hover:bg-primary/5 focus-visible:ring-ring flex items-center justify-center gap-2 rounded-xl border-2 border-dashed px-4 py-4 text-sm font-medium transition-colors focus:outline-none focus-visible:ring-2", children: [_jsx(Plus, { className: "h-4 w-4", "aria-hidden": true }), "Add Field"] }));
    }
    return (_jsxs("div", { className: "bg-card border-border flex flex-col gap-4 rounded-xl border p-5 shadow-sm", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h3", { className: "text-foreground text-sm font-medium", children: "Add Field" }), _jsx("button", { type: "button", onClick: () => {
                            reset();
                            setOpen(false);
                        }, className: "text-muted-foreground hover:text-foreground text-sm transition-colors", children: "Cancel" })] }), _jsx("div", { role: "radiogroup", "aria-label": "Field type", className: "grid grid-cols-2 gap-2 sm:grid-cols-3 xl:grid-cols-4", children: ADDABLE_FIELD_TYPES.map((t) => {
                    const selected = fieldType === t.type;
                    return (_jsxs("button", { type: "button", role: "radio", "aria-checked": selected, onClick: () => setFieldType(t.type), className: `focus-visible:ring-ring flex flex-col items-start gap-0.5 rounded-lg border p-2.5 text-left transition-colors focus:outline-none focus-visible:ring-2 ${selected
                            ? 'border-primary bg-primary/5'
                            : 'border-border hover:border-primary/40 hover:bg-accent'}`, children: [_jsx("span", { className: "text-foreground text-sm font-medium", children: fieldTypeLabel(t.type) }), _jsx("span", { className: "text-muted-foreground text-xs", children: t.desc })] }, t.type));
                }) }), fieldType && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: "af-name", className: "text-foreground text-sm font-medium", children: "Field Name" }), _jsx("input", { id: "af-name", value: name, onChange: (e) => setName(e.target.value), placeholder: "e.g. Client Name", className: "border-border bg-background text-foreground focus:border-primary focus:ring-primary/30 w-full rounded-lg border px-3 py-1.5 text-sm focus:ring-2 focus:outline-none" })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: "af-key", className: "text-foreground text-sm font-medium", children: "Field Key" }), _jsx("input", { id: "af-key", value: key, readOnly: true, "aria-describedby": duplicate ? 'af-key-error' : undefined, className: "border-border bg-muted text-muted-foreground w-full rounded-lg border px-3 py-1.5 font-mono text-sm focus:outline-none" }), duplicate && (_jsxs("span", { id: "af-key-error", className: "text-destructive text-xs", children: ["A field named ", _jsx("code", { className: "font-mono", children: key }), " already exists on this type."] }))] })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: "af-help", className: "text-foreground text-sm font-medium", children: "Help Text (optional)" }), _jsx("input", { id: "af-help", value: helpText, onChange: (e) => setHelpText(e.target.value), placeholder: "Shown to editors as a hint", className: "border-border bg-background text-foreground focus:border-primary focus:ring-primary/30 w-full rounded-lg border px-3 py-1.5 text-sm focus:ring-2 focus:outline-none" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Toggle, { id: "af-required", checked: required, onCheckedChange: setRequired, "aria-labelledby": "af-required-label" }), _jsx("label", { id: "af-required-label", htmlFor: "af-required", className: "text-foreground text-sm", children: "Required field" })] }), snippet && !duplicate && (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-foreground text-sm font-medium", children: ["Add to ", _jsxs("code", { className: "font-mono", children: ["collections.", detail.slug, ".fields"] })] }), _jsxs("button", { type: "button", onClick: copy, className: "border-border bg-background text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs font-medium transition-colors", children: [copied ? (_jsx(Check, { className: "h-3.5 w-3.5", "aria-hidden": true })) : (_jsx(Copy, { className: "h-3.5 w-3.5", "aria-hidden": true })), copied ? 'Copied' : 'Copy snippet'] })] }), _jsx("pre", { className: "border-border bg-muted text-foreground overflow-x-auto rounded-lg border p-3 text-xs leading-relaxed", children: _jsx("code", { children: snippet }) }), _jsxs("p", { className: "text-muted-foreground text-xs", children: ["Paste the line into the type's ", _jsx("code", { className: "font-mono", children: "fields" }), " map in", ' ', _jsx("code", { className: "font-mono", children: "actuate.config.ts" }), " and redeploy \u2014 the field appears in the editor automatically."] })] }))] }))] }));
}
// ─── Loading / notice states ─────────────────────────────────────────
function EditorSkeleton() {
    return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsx("div", { className: "border-border bg-card border-b px-6 py-4 sm:px-6", children: _jsx("div", { className: "bg-muted h-5 w-48 animate-pulse rounded" }) }), _jsxs("div", { className: "flex flex-col gap-6 p-4 sm:p-6 lg:flex-row", children: [_jsx("div", { className: "flex w-full flex-col gap-4 lg:w-[340px]", children: Array.from({ length: 3 }).map((_, i) => (_jsx("div", { className: "bg-card border-border h-32 animate-pulse rounded-xl border" }, i))) }), _jsx("div", { className: "bg-card border-border h-64 flex-1 animate-pulse rounded-xl border" })] })] }));
}
function CenteredNotice({ title, body, actionLabel, onAction, }) {
    return (_jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-2 p-8 text-center", children: [_jsx(FileQuestion, { className: "text-muted-foreground h-6 w-6", "aria-hidden": true }), _jsx("div", { className: "text-foreground text-sm font-medium", children: title }), body && _jsx("p", { className: "text-muted-foreground text-sm", children: body }), _jsx("button", { type: "button", onClick: onAction, className: "text-primary mt-2 text-sm font-medium hover:underline", children: actionLabel })] }));
}
//# sourceMappingURL=PostTypeEditor.js.map