'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Search, Plus, Trash2, ChevronLeft, ChevronRight, Loader2, FileText, MoreHorizontal, } from 'lucide-react';
import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
import { toast } from 'sonner';
import { cmsApi } from '../lib/api.js';
import { useApiData } from '../lib/useApiData.js';
import { editPathForDoc, newPathForCollection } from '../lib/collection-routes.js';
function resolveCollection(config, slug) {
    if (!config?.collections)
        return undefined;
    const list = Array.isArray(config.collections)
        ? config.collections
        : Object.values(config.collections);
    return list.find((c) => c.slug === slug);
}
function resolveLabel(config, slug) {
    return resolveCollection(config, slug)?.labels ?? { singular: slug, plural: slug };
}
/** True for array fields shaped like tags: a single required text sub-field. */
function isTagShapedArray(field) {
    if (field?.type !== 'array' || !field.fields)
        return false;
    const subs = Object.values(field.fields);
    return subs.length === 1 && subs[0]?.type === 'text';
}
/**
 * Facetable fields for the filter bar (taxonomy Phase B): structured selects
 * use their config options; free-text `category` and tag-shaped arrays load
 * the collection's in-use values. Capped so the bar stays scannable.
 */
function facetFieldsFor(config, slug) {
    const fields = resolveCollection(config, slug)?.fields;
    if (!fields || typeof fields !== 'object')
        return [];
    const out = [];
    for (const [name, field] of Object.entries(fields)) {
        if (field?.hidden)
            continue;
        if (field?.type === 'select' && Array.isArray(field.options)) {
            out.push({ name, label: field.label ?? name, source: 'options', options: field.options });
        }
        else if (field?.type === 'text' && name === 'category') {
            out.push({ name, label: field.label ?? 'Category', source: 'values' });
        }
        else if (isTagShapedArray(field)) {
            out.push({ name, label: field.label ?? name, source: 'values' });
        }
        if (out.length >= 3)
            break;
    }
    return out;
}
/** Read a doc's display value for a facet column (select values map to labels). */
function facetCellValue(doc, facet) {
    const raw = doc?.data?.[facet.name];
    if (typeof raw === 'string') {
        if (!raw)
            return '';
        const opt = facet.options?.find((o) => o.value === raw);
        return opt?.label ?? raw;
    }
    if (Array.isArray(raw)) {
        const tags = raw
            .map((item) => typeof item === 'string'
            ? item
            : item && typeof item === 'object'
                ? Object.values(item).find((v) => typeof v === 'string')
                : undefined)
            .filter((v) => Boolean(v));
        if (tags.length === 0)
            return '';
        return tags.length > 3 ? `${tags.slice(0, 3).join(', ')} +${tags.length - 3}` : tags.join(', ');
    }
    return '';
}
function statusColor(status) {
    switch (status?.toUpperCase()) {
        case 'PUBLISHED':
            return 'var(--actuate-success-bg, #dcfce7)';
        case 'DRAFT':
            return 'var(--actuate-muted-bg, #f3f4f6)';
        case 'ARCHIVED':
            return 'var(--actuate-warning-bg, #fef9c3)';
        case 'SCHEDULED':
            return 'var(--actuate-info-bg, #dbeafe)';
        default:
            return 'var(--actuate-muted-bg, #f3f4f6)';
    }
}
function statusText(status) {
    switch (status?.toUpperCase()) {
        case 'PUBLISHED':
            return 'var(--actuate-success-text, #166534)';
        case 'DRAFT':
            return 'var(--actuate-muted-text, #374151)';
        case 'ARCHIVED':
            return 'var(--actuate-warning-text, #854d0e)';
        case 'SCHEDULED':
            return 'var(--actuate-info-text, #1e40af)';
        default:
            return 'var(--actuate-muted-text, #374151)';
    }
}
function formatDate(d) {
    if (!d)
        return '—';
    return new Date(d).toLocaleDateString(undefined, {
        month: 'short',
        day: 'numeric',
        year: 'numeric',
    });
}
export function CollectionList({ collectionSlug, config, onNavigate }) {
    const labels = useMemo(() => resolveLabel(config, collectionSlug), [config, collectionSlug]);
    const facets = useMemo(() => facetFieldsFor(config, collectionSlug), [config, collectionSlug]);
    // Post-type and Pages collections open in dedicated editors — never the
    // generic `/:collection/:id` route (which 404s for a `posts`-slugged post
    // collection and strips section data for any post type).
    const collectionDef = useMemo(() => resolveCollection(config, collectionSlug), [config, collectionSlug]);
    const editPath = useCallback((id) => editPathForDoc(collectionDef, collectionSlug, String(id)), [collectionDef, collectionSlug]);
    const newPath = useCallback(() => newPathForCollection(collectionDef, collectionSlug), [collectionDef, collectionSlug]);
    const [page, setPage] = useState(1);
    const [search, setSearch] = useState('');
    const [debouncedSearch, setDebouncedSearch] = useState('');
    const [sort, setSort] = useState(null);
    const [order, setOrder] = useState('asc');
    const [selected, setSelected] = useState(new Set());
    const [filters, setFilters] = useState({});
    // In-use values per `values`-sourced facet, fetched once per collection.
    const [facetValues, setFacetValues] = useState({});
    const searchTimer = useRef(undefined);
    useEffect(() => {
        clearTimeout(searchTimer.current);
        searchTimer.current = setTimeout(() => {
            setDebouncedSearch(search);
            setPage(1);
        }, 300);
        return () => clearTimeout(searchTimer.current);
    }, [search]);
    const endpoint = useMemo(() => {
        let url = `/collections/${collectionSlug}?page=${page}&pageSize=25`;
        if (debouncedSearch)
            url += `&search=${encodeURIComponent(debouncedSearch)}`;
        if (sort)
            url += `&sort=${sort}&order=${order}`;
        for (const [field, value] of Object.entries(filters)) {
            if (value)
                url += `&filter.${encodeURIComponent(field)}=${encodeURIComponent(value)}`;
        }
        return url;
    }, [collectionSlug, page, debouncedSearch, sort, order, filters]);
    const { data, loading, error, refetch } = useApiData(endpoint);
    const docs = data?.docs ?? [];
    const total = data?.total ?? 0;
    const totalPages = Math.max(1, Math.ceil(total / 25));
    useEffect(() => {
        setPage(1);
        setSelected(new Set());
        setSearch('');
        setFilters({});
        setFacetValues({});
    }, [collectionSlug]);
    // Load in-use values for facets that aren't config-defined selects.
    useEffect(() => {
        let cancelled = false;
        for (const facet of facets) {
            if (facet.source !== 'values')
                continue;
            cmsApi(`/collections/${collectionSlug}/field-values?field=${encodeURIComponent(facet.name)}`).then((res) => {
                if (cancelled || !res.data?.values)
                    return;
                setFacetValues((prev) => ({
                    ...prev,
                    [facet.name]: res.data.values.map((v) => v.value),
                }));
            });
        }
        return () => {
            cancelled = true;
        };
    }, [collectionSlug, facets]);
    const setFilter = useCallback((field, value) => {
        setFilters((prev) => {
            const next = { ...prev };
            if (value)
                next[field] = value;
            else
                delete next[field];
            return next;
        });
        setPage(1);
    }, []);
    const toggleSort = useCallback((field) => {
        setSort((prev) => {
            if (prev === field) {
                setOrder((o) => (o === 'asc' ? 'desc' : 'asc'));
                return field;
            }
            setOrder('asc');
            return field;
        });
    }, []);
    const toggleSelect = (id) => setSelected((prev) => {
        const s = new Set(prev);
        s.has(id) ? s.delete(id) : s.add(id);
        return s;
    });
    const toggleAll = (checked) => setSelected(checked ? new Set(docs.map((d) => String(d.id))) : new Set());
    const bulkAction = async (action) => {
        const ids = [...selected];
        for (const id of ids) {
            if (action === 'delete') {
                await cmsApi(`/collections/${collectionSlug}/${id}`, { method: 'DELETE' });
            }
            else {
                await cmsApi(`/collections/${collectionSlug}/${id}`, {
                    method: 'PUT',
                    body: JSON.stringify({ status: action === 'publish' ? 'PUBLISHED' : 'DRAFT' }),
                });
            }
        }
        const verb = action === 'delete' ? 'deleted' : action === 'publish' ? 'published' : 'unpublished';
        toast.success(`${ids.length} ${ids.length === 1 ? labels.singular : labels.plural} ${verb}`);
        setSelected(new Set());
        refetch();
    };
    const SortCol = ({ field, children }) => (_jsxs("button", { type: "button", onClick: () => toggleSort(field), className: "flex items-center gap-1 text-xs font-medium transition-opacity hover:opacity-80", style: { color: 'var(--actuate-text-secondary, #6b7280)' }, children: [children, sort === field && _jsx("span", { children: order === 'asc' ? '↑' : '↓' })] }));
    if (loading && docs.length === 0) {
        return (_jsx("div", { className: "flex h-64 items-center justify-center p-4", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin", style: { color: 'var(--actuate-primary, #2563eb)' } }) }));
    }
    return (_jsxs("div", { className: "flex h-full flex-col p-3 pr-6 sm:p-4 sm:pr-8", children: [_jsxs("div", { className: "mb-4 flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl font-medium sm:text-2xl", style: { color: 'var(--actuate-text, #111827)' }, children: labels.plural }), _jsxs("p", { className: "text-sm", style: { color: 'var(--actuate-text-secondary, #6b7280)' }, children: [total, " total"] })] }), _jsxs("button", { onClick: () => onNavigate(newPath()), className: "flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium text-white transition-colors", style: { background: 'var(--actuate-primary, #2563eb)' }, children: [_jsx(Plus, { className: "h-4 w-4" }), " New ", labels.singular] })] }), _jsxs("div", { className: "mb-4 flex flex-wrap items-center gap-2", children: [_jsxs("div", { className: "relative min-w-[200px] flex-1", children: [_jsx(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2", style: { color: 'var(--actuate-text-muted, #9ca3af)' } }), _jsx("input", { type: "text", placeholder: `Search ${labels.plural.toLowerCase()}...`, value: search, onChange: (e) => setSearch(e.target.value), className: "w-full rounded-lg border py-2 pr-3 pl-9 text-sm focus:ring-2 focus:outline-none", style: {
                                    borderColor: 'var(--actuate-border, #d1d5db)',
                                    color: 'var(--actuate-text, #111827)',
                                } })] }), facets.map((facet) => {
                        const values = facet.source === 'options'
                            ? (facet.options ?? [])
                            : (facetValues[facet.name] ?? []).map((v) => ({ label: v, value: v }));
                        if (values.length === 0)
                            return null;
                        return (_jsxs("select", { "aria-label": `Filter by ${facet.label}`, value: filters[facet.name] ?? '', onChange: (e) => setFilter(facet.name, e.target.value), className: "rounded-lg border px-3 py-2 text-sm focus:ring-2 focus:outline-none", style: {
                                borderColor: 'var(--actuate-border, #d1d5db)',
                                color: filters[facet.name]
                                    ? 'var(--actuate-text, #111827)'
                                    : 'var(--actuate-text-secondary, #6b7280)',
                            }, children: [_jsxs("option", { value: "", children: ["All ", facet.label.toLowerCase()] }), values.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value)))] }, facet.name));
                    }), Object.keys(filters).length > 0 && (_jsx("button", { type: "button", onClick: () => setFilters({}), className: "rounded-lg px-2 py-2 text-sm underline transition-opacity hover:opacity-75", style: { color: 'var(--actuate-text-secondary, #6b7280)' }, children: "Clear filters" }))] }), selected.size > 0 && (_jsxs("div", { className: "mb-4 flex flex-wrap items-center justify-between gap-2 rounded-lg p-3", style: {
                    background: 'var(--actuate-info-bg, #eff6ff)',
                    borderColor: 'var(--actuate-info-border, #bfdbfe)',
                    borderWidth: 1,
                    borderStyle: 'solid',
                }, children: [_jsxs("span", { className: "text-sm", style: { color: 'var(--actuate-info-text, #1e40af)' }, children: [selected.size, " selected"] }), _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { onClick: () => bulkAction('publish'), className: "rounded-lg px-3 py-1.5 text-sm text-white", style: { background: 'var(--actuate-success, #16a34a)' }, children: "Publish" }), _jsx("button", { onClick: () => bulkAction('unpublish'), className: "rounded-lg px-3 py-1.5 text-sm text-white", style: { background: 'var(--actuate-warning, #ca8a04)' }, children: "Unpublish" }), _jsxs("button", { onClick: () => bulkAction('delete'), className: "rounded-lg px-3 py-1.5 text-sm text-white", style: { background: 'var(--actuate-danger, #dc2626)' }, children: [_jsx(Trash2, { className: "-mt-0.5 mr-1 inline h-3.5 w-3.5" }), "Delete"] })] })] })), error && (_jsxs("div", { className: "mb-4 rounded-lg p-3 text-sm", style: {
                    background: 'var(--actuate-danger-bg, #fef2f2)',
                    color: 'var(--actuate-danger-text, #991b1b)',
                }, children: [error, " \u2014", ' ', _jsx("button", { onClick: refetch, className: "underline", children: "retry" })] })), docs.length === 0 && !loading ? (_jsxs("div", { className: "flex flex-1 flex-col items-center justify-center rounded-lg border p-8", style: {
                    borderColor: 'var(--actuate-border, #d1d5db)',
                    color: 'var(--actuate-text-secondary, #6b7280)',
                }, children: [_jsx(FileText, { className: "mb-3 h-10 w-10 opacity-40" }), _jsxs("p", { className: "mb-3 text-sm", children: ["No ", labels.plural.toLowerCase(), " found"] }), _jsxs("button", { onClick: () => onNavigate(newPath()), className: "rounded-lg px-4 py-2 text-sm text-white", style: { background: 'var(--actuate-primary, #2563eb)' }, children: ["Create ", labels.singular] })] })) : (_jsx("div", { className: "flex-1 overflow-auto rounded-lg border", style: { borderColor: 'var(--actuate-border, #d1d5db)' }, children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "sticky top-0", style: {
                                background: 'var(--actuate-surface-alt, #f9fafb)',
                                borderBottom: '1px solid var(--actuate-border, #d1d5db)',
                            }, children: _jsxs("tr", { children: [_jsx("th", { className: "w-10 px-3 py-2 text-left", children: _jsx("input", { type: "checkbox", checked: selected.size === docs.length && docs.length > 0, onChange: (e) => toggleAll(e.target.checked), className: "rounded" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortCol, { field: "title", children: "Title" }) }), facets.map((facet) => (_jsx("th", { className: "px-3 py-2 text-left text-xs font-medium", style: { color: 'var(--actuate-text-secondary, #6b7280)' }, children: facet.label }, facet.name))), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortCol, { field: "status", children: "Status" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortCol, { field: "updatedAt", children: "Updated" }) }), _jsx("th", { className: "px-3 py-2 text-left text-xs font-medium", style: { color: 'var(--actuate-text-secondary, #6b7280)' }, children: "Actions" })] }) }), _jsx("tbody", { children: docs.map((doc) => (_jsxs("tr", { className: "transition-colors hover:opacity-95", style: { borderBottom: '1px solid var(--actuate-border, #e5e7eb)' }, children: [_jsx("td", { className: "px-3 py-2", children: _jsx("input", { type: "checkbox", checked: selected.has(String(doc.id)), onChange: () => toggleSelect(String(doc.id)), className: "rounded" }) }), _jsx("td", { className: "px-3 py-2", children: _jsx("button", { type: "button", onClick: () => onNavigate(editPath(doc.id)), className: "text-left font-medium hover:underline", style: { color: 'var(--actuate-text, #111827)' }, children: doc.title || doc.name || `#${doc.id}` }) }), facets.map((facet) => (_jsx("td", { className: "max-w-[200px] truncate px-3 py-2", style: { color: 'var(--actuate-text-secondary, #6b7280)' }, title: facetCellValue(doc, facet) || undefined, children: facetCellValue(doc, facet) || '—' }, facet.name))), _jsx("td", { className: "px-3 py-2", children: _jsx("span", { className: "inline-block rounded-full px-2 py-0.5 text-xs font-medium", style: { background: statusColor(doc.status), color: statusText(doc.status) }, children: doc.status ?? 'DRAFT' }) }), _jsx("td", { className: "px-3 py-2", style: { color: 'var(--actuate-text-secondary, #6b7280)' }, children: formatDate(doc.updatedAt) }), _jsx("td", { className: "px-3 py-2", children: _jsx("button", { type: "button", onClick: () => onNavigate(editPath(doc.id)), className: "rounded p-1.5 transition-opacity hover:opacity-75", title: "Edit", children: _jsx(MoreHorizontal, { className: "h-4 w-4", style: { color: 'var(--actuate-text-secondary, #6b7280)' } }) }) })] }, doc.id))) })] }) })), totalPages > 1 && (_jsxs("div", { className: "mt-4 flex items-center justify-between text-sm", style: { color: 'var(--actuate-text-secondary, #6b7280)' }, children: [_jsxs("span", { children: ["Page ", page, " of ", totalPages] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs("button", { disabled: page <= 1, onClick: () => setPage((p) => p - 1), className: "flex items-center gap-1 rounded-lg border px-3 py-1.5 transition-opacity disabled:opacity-40", style: { borderColor: 'var(--actuate-border, #d1d5db)' }, children: [_jsx(ChevronLeft, { className: "h-4 w-4" }), " Previous"] }), _jsxs("button", { disabled: page >= totalPages, onClick: () => setPage((p) => p + 1), className: "flex items-center gap-1 rounded-lg border px-3 py-1.5 transition-opacity disabled:opacity-40", style: { borderColor: 'var(--actuate-border, #d1d5db)' }, children: ["Next ", _jsx(ChevronRight, { className: "h-4 w-4" })] })] })] }))] }));
}
//# sourceMappingURL=CollectionList.js.map