/**
 * Express routes for workspace CRUD, doc/container/tag operations.
 * Mounted in index.ts to keep the main file lean.
 */
import { Router } from 'express';
import { listWorkspaces, getWorkspace, createWorkspace, deleteWorkspace, reorderWorkspaces, addDoc, removeDoc, moveDoc, reorderDoc, addContainerToWorkspace, removeContainer, renameContainer, renameWorkspace, reorderContainer, crossMoveContainer, promoteContainerToWorkspace, } from './workspaces.js';
import { findNode } from './workspace-tree.js';
import { deleteDocument } from './documents.js';
function collectDocFilesInSubtree(nodes, out = []) {
    for (const n of nodes) {
        if (n.type === 'doc')
            out.push(n.file);
        else if (n.type === 'container')
            collectDocFilesInSubtree(n.items, out);
    }
    return out;
}
export function createWorkspaceRouter(b) {
    const router = Router();
    router.get('/api/workspaces', (_req, res) => {
        res.json(listWorkspaces());
    });
    router.post('/api/workspaces', (req, res) => {
        try {
            const result = createWorkspace({
                title: req.body.title,
                voiceProfileId: req.body.voiceProfileId,
            });
            b.broadcastWorkspacesChanged();
            res.json(result);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    // Static paths before parameterized — otherwise :filename captures "reorder"
    router.put('/api/workspaces/reorder', (req, res) => {
        try {
            const { order } = req.body;
            if (!Array.isArray(order))
                return res.status(400).json({ error: 'order must be an array' });
            reorderWorkspaces(order);
            b.broadcastWorkspacesChanged();
            res.json({ success: true });
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    // Promote container to standalone workspace
    router.post('/api/workspaces/promote-container', (req, res) => {
        try {
            const { sourceWorkspace, containerId, afterWorkspaceFilename } = req.body;
            if (!sourceWorkspace || !containerId)
                return res.status(400).json({ error: 'sourceWorkspace and containerId required' });
            const result = promoteContainerToWorkspace(sourceWorkspace, containerId, afterWorkspaceFilename ?? null);
            b.broadcastWorkspacesChanged();
            res.json(result);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    router.get('/api/workspaces/:filename', (req, res) => {
        try {
            res.json(getWorkspace(req.params.filename));
        }
        catch (err) {
            res.status(404).json({ error: err.message });
        }
    });
    router.put('/api/workspaces/:filename', (req, res) => {
        try {
            const ws = renameWorkspace(req.params.filename, req.body.title);
            b.broadcastWorkspacesChanged();
            res.json(ws);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    router.delete('/api/workspaces/:filename', async (req, res) => {
        try {
            await deleteWorkspace(req.params.filename);
            b.broadcastWorkspacesChanged();
            res.json({ success: true });
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    // Doc operations
    router.post('/api/workspaces/:filename/docs', (req, res) => {
        try {
            const ws = addDoc(req.params.filename, req.body.containerId ?? null, req.body.file, req.body.title || req.body.file, req.body.afterFile ?? null);
            b.broadcastWorkspacesChanged();
            res.json(ws);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    router.delete('/api/workspaces/:filename/docs/:docFile', (req, res) => {
        try {
            const ws = removeDoc(req.params.filename, req.params.docFile);
            b.broadcastWorkspacesChanged();
            res.json(ws);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    router.put('/api/workspaces/:filename/docs/:docFile/move', (req, res) => {
        try {
            const ws = moveDoc(req.params.filename, req.params.docFile, req.body.targetContainerId ?? null, req.body.afterFile ?? null);
            b.broadcastWorkspacesChanged();
            res.json(ws);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    router.put('/api/workspaces/:filename/docs/:docFile/reorder', (req, res) => {
        try {
            const ws = reorderDoc(req.params.filename, req.params.docFile, req.body.afterFile ?? null);
            b.broadcastWorkspacesChanged();
            res.json(ws);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    // Container operations
    router.post('/api/workspaces/:filename/containers', (req, res) => {
        try {
            const result = addContainerToWorkspace(req.params.filename, req.body.parentContainerId ?? null, req.body.name);
            b.broadcastWorkspacesChanged();
            res.json(result);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    router.delete('/api/workspaces/:filename/containers/:containerId', async (req, res) => {
        try {
            const cascade = req.query.cascade === 'true' || req.query.cascade === '1';
            let deletedDocs = 0;
            if (cascade) {
                // Find the container, collect all docs in its subtree, delete them from disk.
                const current = getWorkspace(req.params.filename);
                const found = findNode(current.root, (n) => n.type === 'container' && n.id === req.params.containerId);
                if (found && found.node.type === 'container') {
                    const files = collectDocFilesInSubtree(found.node.items);
                    for (const file of files) {
                        try {
                            await deleteDocument(file);
                            deletedDocs++;
                        }
                        catch { /* swallow per-doc failures; keep going */ }
                    }
                }
            }
            const ws = removeContainer(req.params.filename, req.params.containerId);
            b.broadcastWorkspacesChanged();
            res.json({ ...ws, deletedDocs });
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    router.put('/api/workspaces/:filename/containers/:containerId', (req, res) => {
        try {
            let ws;
            if (req.body.name !== undefined) {
                ws = renameContainer(req.params.filename, req.params.containerId, req.body.name);
            }
            b.broadcastWorkspacesChanged();
            res.json(ws || getWorkspace(req.params.filename));
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    router.put('/api/workspaces/:filename/containers/:containerId/reorder', (req, res) => {
        try {
            const ws = reorderContainer(req.params.filename, req.params.containerId, req.body.afterIdentifier ?? null);
            b.broadcastWorkspacesChanged();
            res.json(ws);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    // Cross-workspace container move
    router.post('/api/workspaces/:targetFilename/containers/:containerId/cross-move', (req, res) => {
        try {
            const { sourceWorkspace } = req.body;
            if (!sourceWorkspace)
                return res.status(400).json({ error: 'sourceWorkspace required' });
            const ws = crossMoveContainer(sourceWorkspace, req.params.targetFilename, req.params.containerId, req.body.targetContainerId ?? null, req.body.afterIdentifier ?? null);
            b.broadcastWorkspacesChanged();
            res.json(ws);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    // Cross-workspace move (from one workspace to another)
    router.post('/api/workspaces/:targetFilename/docs/:docFile/cross-move', (req, res) => {
        try {
            const { sourceWorkspace } = req.body;
            removeDoc(sourceWorkspace, req.params.docFile);
            const ws = addDoc(req.params.targetFilename, req.body.containerId ?? null, req.params.docFile, req.body.title || req.params.docFile, req.body.afterFile ?? null);
            b.broadcastWorkspacesChanged();
            res.json(ws);
        }
        catch (err) {
            res.status(400).json({ error: err.message });
        }
    });
    return router;
}
