import { guardedDb } from '../guarded-db.js';
import { json, errorResponse, internalError, hasModel, requireAuth, WRITE_ROLES, requireRole, } from '../route-helpers.js';
export function registerFolderRoutes(router) {
    const db = guardedDb;
    // ---------------------------------------------------------------------------
    // Folder routes
    // ---------------------------------------------------------------------------
    router.get('/folders', async (request) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const url = new URL(request.url);
            const scope = url.searchParams.get('scope');
            if (!scope)
                return errorResponse('scope query parameter is required', 400);
            const folders = await db().folder.findMany({
                where: { scope },
                orderBy: [{ position: 'asc' }, { name: 'asc' }],
            });
            const buildTree = (parentId) => folders
                .filter((f) => f.parentId === parentId)
                .map((f) => ({ ...f, children: buildTree(f.id) }));
            return json({ data: buildTree(null) });
        }
        catch (err) {
            return internalError(err);
        }
    });
    router.post('/folders', async (request) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, WRITE_ROLES);
            if (roleErr)
                return roleErr;
            const body = (await request.json());
            if (!body.name || !body.scope)
                return errorResponse('name and scope are required', 400);
            // A child folder MUST live in the same scope as its parent — without
            // this check, a 'documents' folder could be reparented under a 'media'
            // folder, hiding it from both UIs.
            if (body.parentId) {
                const parent = await db().folder.findUnique({ where: { id: body.parentId } });
                if (!parent)
                    return errorResponse('Parent folder not found', 404);
                if (parent.scope !== body.scope) {
                    return errorResponse('Parent folder is in a different scope', 400);
                }
            }
            const folder = await db().folder.create({
                data: {
                    name: body.name,
                    scope: body.scope,
                    parentId: body.parentId ?? null,
                },
            });
            return json({ data: folder }, 201);
        }
        catch (err) {
            return internalError(err);
        }
    });
    router.put('/folders/:id', async (request, params) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, WRITE_ROLES);
            if (roleErr)
                return roleErr;
            const body = (await request.json());
            const existing = await db().folder.findUnique({ where: { id: params.id } });
            if (!existing)
                return errorResponse('Folder not found', 404);
            // Prevent reparenting into a different scope, and prevent making a folder
            // a descendant of itself (which would create a cycle).
            if (body.parentId !== undefined && body.parentId !== null) {
                if (body.parentId === params.id) {
                    return errorResponse('Folder cannot be its own parent', 400);
                }
                const parent = await db().folder.findUnique({ where: { id: body.parentId } });
                if (!parent)
                    return errorResponse('Parent folder not found', 404);
                if (parent.scope !== existing.scope) {
                    return errorResponse('Parent folder is in a different scope', 400);
                }
            }
            const data = {};
            if (body.name !== undefined)
                data.name = body.name;
            if (body.parentId !== undefined)
                data.parentId = body.parentId;
            if (body.position !== undefined)
                data.position = body.position;
            const folder = await db().folder.update({
                where: { id: params.id },
                data,
            });
            return json({ data: folder });
        }
        catch (err) {
            return internalError(err);
        }
    });
    router.delete('/folders/:id', async (request, params) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, WRITE_ROLES);
            if (roleErr)
                return roleErr;
            // We don't cascade-delete the contents — they would silently vanish.
            // Instead, refuse to delete a folder that still has documents, media,
            // or sub-folders inside it.
            const d = db();
            const folder = await d.folder.findUnique({ where: { id: params.id } });
            if (!folder)
                return errorResponse('Folder not found', 404);
            const [docCount, mediaCount, childCount] = await Promise.all([
                hasModel(d, 'document')
                    ? d.document.count({ where: { folderId: params.id, deletedAt: null } })
                    : 0,
                hasModel(d, 'media') ? d.media.count({ where: { folderId: params.id } }) : 0,
                d.folder.count({ where: { parentId: params.id } }),
            ]);
            if (docCount + mediaCount + childCount > 0) {
                return errorResponse(`Folder is not empty (${docCount} documents, ${mediaCount} media, ${childCount} sub-folders). Move or delete its contents first.`, 409);
            }
            await d.folder.delete({ where: { id: params.id } });
            return json({ data: { success: true } });
        }
        catch (err) {
            return internalError(err);
        }
    });
    router.put('/documents/:id/folder', async (request, params) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, WRITE_ROLES);
            if (roleErr)
                return roleErr;
            const body = (await request.json());
            // Confirm the target folder is in the documents scope before moving in.
            if (body.folderId) {
                const target = await db().folder.findUnique({ where: { id: body.folderId } });
                if (!target)
                    return errorResponse('Folder not found', 404);
                if (target.scope !== 'documents' && target.scope !== 'collections') {
                    return errorResponse('Target folder is not a documents folder', 400);
                }
            }
            await db().document.update({
                where: { id: params.id },
                data: { folderId: body.folderId ?? null },
            });
            return json({ data: { success: true } });
        }
        catch (err) {
            return internalError(err);
        }
    });
    router.put('/media/:id/folder', async (request, params) => {
        try {
            const auth = await requireAuth(request);
            if (auth.error)
                return auth.error;
            const roleErr = requireRole(auth.session.role, WRITE_ROLES);
            if (roleErr)
                return roleErr;
            const body = (await request.json());
            if (body.folderId) {
                const target = await db().folder.findUnique({ where: { id: body.folderId } });
                if (!target)
                    return errorResponse('Folder not found', 404);
                if (target.scope !== 'media') {
                    return errorResponse('Target folder is not a media folder', 400);
                }
            }
            await db().media.update({
                where: { id: params.id },
                data: { folderId: body.folderId ?? null },
            });
            return json({ data: { success: true } });
        }
        catch (err) {
            return internalError(err);
        }
    });
}
//# sourceMappingURL=folders.js.map