import { logEvent } from '../../security/audit.js';
import { BUILT_IN_TEMPLATES } from '../../page-builder/templates.js';
import { validateTree } from '../../page-builder/validate.js';
import { guardedDb } from '../guarded-db.js';
import { json, errorResponse, internalError, hasModel, modelNotAvailable, safeCount, requireAuth, ADMIN_ROLES, requireRole, } from '../route-helpers.js';
export function registerPageTemplateRoutes(router) {
    const db = guardedDb;
    // ---------------------------------------------------------------------------
    // Page Templates
    // ---------------------------------------------------------------------------
    async function seedBuiltInTemplates(d) {
        for (const [key, template] of Object.entries(BUILT_IN_TEMPLATES)) {
            await d.pageTemplate.upsert({
                where: { id: `builtin-${key}` },
                create: {
                    id: `builtin-${key}`,
                    name: template.name,
                    description: template.description,
                    category: template.category,
                    tree: template.tree,
                    builtIn: true,
                },
                update: {
                    name: template.name,
                    description: template.description,
                    category: template.category,
                    tree: template.tree,
                },
            });
        }
    }
    router.get('/page-templates', async (request) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, ADMIN_ROLES);
            if (roleErr)
                return roleErr;
            const d = db();
            if (!hasModel(d, 'pageTemplate'))
                return modelNotAvailable('PageTemplate');
            const url = new URL(request.url, 'http://localhost');
            const category = url.searchParams.get('category');
            const collection = url.searchParams.get('collection');
            const builtInCount = await safeCount(d.pageTemplate, { builtIn: true });
            if (builtInCount === 0) {
                await seedBuiltInTemplates(d);
            }
            const where = {};
            if (category)
                where.category = category;
            const templates = await d.pageTemplate.findMany({
                where,
                orderBy: [{ builtIn: 'desc' }, { updatedAt: 'desc' }],
            });
            // When a `collection` filter is supplied, reorder the response so the
            // suggested templates for that collection bubble to the top. The admin
            // "Create new" picker uses this so blog posts default to `blog-post`,
            // case studies to `case-study`, etc., without forcing the user to scan
            // every template alphabetically.
            if (collection) {
                const { getTemplatesForCollection } = await import('../../collections/presets.js');
                const { primary, alternates } = getTemplatesForCollection(collection);
                const suggestionOrder = new Map();
                if (primary)
                    suggestionOrder.set(`builtin-${primary}`, 0);
                alternates.forEach((alt, i) => suggestionOrder.set(`builtin-${alt}`, i + 1));
                templates.sort((a, b) => {
                    const ai = suggestionOrder.has(a.id) ? suggestionOrder.get(a.id) : 100;
                    const bi = suggestionOrder.has(b.id) ? suggestionOrder.get(b.id) : 100;
                    return ai - bi;
                });
                const annotated = templates.map((t) => ({
                    ...t,
                    suggested: suggestionOrder.has(t.id),
                    suggestionRank: suggestionOrder.get(t.id) ?? null,
                }));
                return json({
                    data: annotated,
                    suggestion: {
                        collection,
                        primary: primary ? `builtin-${primary}` : null,
                        alternates: alternates.map((a) => `builtin-${a}`),
                    },
                });
            }
            return json({ data: templates });
        }
        catch (err) {
            return internalError(err, 'page-templates list');
        }
    });
    router.get('/page-templates/:id', async (request, params) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, ADMIN_ROLES);
            if (roleErr)
                return roleErr;
            const d = db();
            if (!hasModel(d, 'pageTemplate'))
                return modelNotAvailable('PageTemplate');
            const template = await d.pageTemplate.findUnique({ where: { id: params.id } });
            if (!template)
                return errorResponse('Template not found', 404);
            return json({ data: template });
        }
        catch (err) {
            return internalError(err, 'page-templates get');
        }
    });
    router.post('/page-templates', async (request) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, ADMIN_ROLES);
            if (roleErr)
                return roleErr;
            const d = db();
            if (!hasModel(d, 'pageTemplate'))
                return modelNotAvailable('PageTemplate');
            const body = (await request.json());
            if (!body.name)
                return errorResponse('name is required', 400);
            if (!body.tree)
                return errorResponse('tree is required', 400);
            const validation = validateTree(body.tree);
            if (!validation.valid) {
                return errorResponse(`Invalid tree: ${validation.errors.join('; ')}`, 400);
            }
            const validCategories = ['landing', 'content', 'utility'];
            const category = body.category || 'content';
            if (!validCategories.includes(category)) {
                return errorResponse('category must be landing, content, or utility', 400);
            }
            const template = await d.pageTemplate.create({
                data: {
                    name: body.name,
                    description: body.description || null,
                    category,
                    tree: body.tree,
                    thumbnail: body.thumbnail || null,
                    builtIn: false,
                },
            });
            await logEvent({
                event: 'settings_changed',
                userId: auth.session.userId,
                details: { action: 'page_template_created', templateId: template.id, name: template.name },
            });
            return json({ data: template }, 201);
        }
        catch (err) {
            return internalError(err, 'page-templates create');
        }
    });
    router.put('/page-templates/:id', async (request, params) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, ADMIN_ROLES);
            if (roleErr)
                return roleErr;
            const d = db();
            if (!hasModel(d, 'pageTemplate'))
                return modelNotAvailable('PageTemplate');
            const existing = await d.pageTemplate.findUnique({ where: { id: params.id } });
            if (!existing)
                return errorResponse('Template not found', 404);
            if (existing.builtIn)
                return errorResponse('Cannot update built-in templates', 403);
            const body = (await request.json());
            const update = {};
            if (body.name !== undefined)
                update.name = body.name;
            if (body.description !== undefined)
                update.description = body.description;
            if (body.thumbnail !== undefined)
                update.thumbnail = body.thumbnail;
            if (body.category !== undefined) {
                const validCategories = ['landing', 'content', 'utility'];
                if (!validCategories.includes(body.category)) {
                    return errorResponse('category must be landing, content, or utility', 400);
                }
                update.category = body.category;
            }
            if (body.tree !== undefined) {
                const validation = validateTree(body.tree);
                if (!validation.valid) {
                    return errorResponse(`Invalid tree: ${validation.errors.join('; ')}`, 400);
                }
                update.tree = body.tree;
            }
            const template = await d.pageTemplate.update({
                where: { id: params.id },
                data: update,
            });
            await logEvent({
                event: 'settings_changed',
                userId: auth.session.userId,
                details: { action: 'page_template_updated', templateId: template.id, name: template.name },
            });
            return json({ data: template });
        }
        catch (err) {
            return internalError(err, 'page-templates update');
        }
    });
    router.delete('/page-templates/:id', async (request, params) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, ADMIN_ROLES);
            if (roleErr)
                return roleErr;
            const d = db();
            if (!hasModel(d, 'pageTemplate'))
                return modelNotAvailable('PageTemplate');
            const existing = await d.pageTemplate.findUnique({ where: { id: params.id } });
            if (!existing)
                return errorResponse('Template not found', 404);
            if (existing.builtIn)
                return errorResponse('Cannot delete built-in templates', 403);
            await d.pageTemplate.delete({ where: { id: params.id } });
            await logEvent({
                event: 'settings_changed',
                userId: auth.session.userId,
                details: { action: 'page_template_deleted', templateId: existing.id, name: existing.name },
            });
            return json({ data: { deleted: true } });
        }
        catch (err) {
            return internalError(err, 'page-templates delete');
        }
    });
    router.post('/page-templates/seed', async (request) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, ADMIN_ROLES);
            if (roleErr)
                return roleErr;
            const d = db();
            if (!hasModel(d, 'pageTemplate'))
                return modelNotAvailable('PageTemplate');
            await seedBuiltInTemplates(d);
            await logEvent({
                event: 'settings_changed',
                userId: auth.session.userId,
                details: { action: 'page_templates_seeded' },
            });
            return json({ data: { seeded: Object.keys(BUILT_IN_TEMPLATES).length } });
        }
        catch (err) {
            return internalError(err, 'page-templates seed');
        }
    });
}
//# sourceMappingURL=page-templates.js.map