/**
 * Posts service — thin client over the CMS REST endpoints, shaped around the
 * data the Posts admin area needs.
 *
 * `fetchPosts` calls the server-side aggregate endpoint `GET /posts`, which
 * does the cross-collection filter / sort / paginate at the DB level (one
 * query + one count) and returns the post rows alongside dataset-wide type
 * counts and the contributor list. This keeps the Posts list O(page) instead
 * of pulling every document per type into the browser, and lets it scale past
 * the old ~500-row-per-type client cap.
 *
 * Access control still lives server-side: the endpoint only returns rows from
 * collections the caller's scope can read.
 */
import { cmsApi } from './api.js';
function isPostsCollection(c) {
    return c.type === 'post' || (typeof c.group === 'string' && c.group.toLowerCase() === 'posts');
}
async function fetchPostCollections() {
    const res = await cmsApi('/collections');
    if (res.error || !res.data)
        return [];
    // `excludeFromPostsAggregate` mirrors the server-side /posts filter: a
    // post-shaped collection with its own workflow stays out of the Posts UI.
    return res.data.filter((c) => !c.hidden && !c.excludeFromPostsAggregate && isPostsCollection(c));
}
export async function fetchPostTypes() {
    const cols = await fetchPostCollections();
    // Counts are filled in by `fetchPosts` so the cards / tabs reflect
    // the same numbers users see in the table. When called from a page
    // that doesn't load posts (the New Post picker), the count stays
    // at 0 until the next fetchPosts call.
    return cols.map(collectionToPostType);
}
function collectionToPostType(c, count = 0) {
    return {
        id: c.slug,
        slug: c.slug,
        name: c.labels.plural,
        singularName: c.labels.singular,
        description: c.description ?? null,
        urlBase: `/${c.urlPrefix || c.slug}`,
        accentColor: c.color ?? null,
        icon: c.icon ?? null,
        postCount: count,
        fieldCount: c.fieldCount,
        active: true,
    };
}
// ─── Authors ─────────────────────────────────────────────────────────
function initialsFromName(name) {
    const trimmed = name?.trim();
    if (!trimmed)
        return '?';
    const parts = trimmed.split(/\s+/);
    const first = parts[0]?.[0] ?? '';
    const last = parts.length > 1 ? (parts[parts.length - 1]?.[0] ?? '') : '';
    return (first + last).toUpperCase() || '?';
}
/** Display date matches the old client behaviour: scheduled/published date when set, else updated. */
function pickDisplayDate(d) {
    if (d.status === 'SCHEDULED' && d.scheduledAt)
        return d.scheduledAt;
    if (d.status === 'PUBLISHED' && d.publishedAt)
        return d.publishedAt;
    return d.updatedAt;
}
function buildPostsQueryString(query) {
    const params = new URLSearchParams();
    if (query.search?.trim())
        params.set('search', query.search.trim());
    if (query.postType && query.postType !== 'all')
        params.set('postType', query.postType);
    if (query.status && query.status !== 'all')
        params.set('status', query.status);
    if (query.author && query.author !== 'all')
        params.set('author', query.author);
    if (query.sortBy)
        params.set('sortBy', query.sortBy);
    if (query.sortDirection)
        params.set('sortDirection', query.sortDirection);
    params.set('page', String(Math.max(1, query.page ?? 1)));
    params.set('pageSize', String(Math.max(1, query.pageSize ?? 10)));
    const qs = params.toString();
    return qs ? `?${qs}` : '';
}
export async function fetchPosts(query = {}) {
    const page = Math.max(1, query.page ?? 1);
    const pageSize = Math.max(1, query.pageSize ?? 10);
    const res = await cmsApi(`/posts${buildPostsQueryString(query)}`);
    if (res.error || !res.data) {
        throw new Error(res.error ?? 'Failed to load posts');
    }
    const r = res.data;
    const typeBySlug = new Map();
    for (const t of r.types)
        typeBySlug.set(t.slug, t);
    const types = r.types.map((t) => ({
        id: t.slug,
        slug: t.slug,
        name: t.plural,
        singularName: t.singular,
        description: t.description ?? null,
        urlBase: `/${t.urlPrefix || t.slug}`,
        accentColor: t.color ?? null,
        icon: t.icon ?? null,
        postCount: t.count,
        fieldCount: t.fieldCount,
        active: true,
    }));
    const posts = r.posts.map((d) => {
        const type = typeBySlug.get(d.collection);
        const authorName = d.author?.name?.trim() || 'Unknown';
        return {
            id: d.id,
            title: d.title ?? '(untitled)',
            slug: d.slug ?? '',
            postTypeId: d.collection,
            postTypeName: type?.singular ?? d.collection,
            postTypeAccentColor: type?.color ?? null,
            authorId: d.author?.id ?? '',
            authorName,
            authorInitials: d.author ? initialsFromName(d.author.name) : '??',
            status: d.status,
            publishDate: d.publishedAt ?? d.scheduledAt ?? null,
            updatedDate: pickDisplayDate(d),
            seoScore: d.seoScore,
            createdAt: d.createdAt,
            updatedAt: d.updatedAt,
        };
    });
    const authors = r.authors
        .map((a) => ({
        id: a.id,
        name: a.name?.trim() || 'Unknown',
        initials: initialsFromName(a.name),
    }))
        .sort((a, b) => a.name.localeCompare(b.name));
    return {
        posts,
        total: r.total,
        page: r.page ?? page,
        pageSize: r.pageSize ?? pageSize,
        types,
        authors,
    };
}
// ─── Bulk mutations ──────────────────────────────────────────────────
export async function bulkUpdatePosts(ids, payload) {
    let ok = 0;
    let failed = 0;
    for (const { postTypeId, id } of ids) {
        const res = await cmsApi(`/collections/${encodeURIComponent(postTypeId)}/${id}`, {
            method: 'PUT',
            body: JSON.stringify(payload),
        });
        if (res.error)
            failed++;
        else
            ok++;
    }
    return { ok, failed };
}
export async function bulkDeletePosts(ids) {
    let ok = 0;
    let failed = 0;
    for (const { postTypeId, id } of ids) {
        const res = await cmsApi(`/collections/${encodeURIComponent(postTypeId)}/${id}`, {
            method: 'DELETE',
        });
        if (res.error)
            failed++;
        else
            ok++;
    }
    return { ok, failed };
}
//# sourceMappingURL=posts-service.js.map