import { Router } from 'express';
import { errorHandler } from './errors.js';
const STATUSES = ['active', 'stale', 'broken'];
const RELATIONS = [
    'depends_on',
    'implements',
    'extends',
    'example_of',
    'contradicts',
    'see_also',
];
export function dependenciesRouter(dependencies, _sections, references, ws) {
    const router = Router();
    router.get('/', (req, res, next) => {
        try {
            const status = typeof req.query.status === 'string' ? req.query.status : undefined;
            const relation = typeof req.query.relation === 'string' ? req.query.relation : undefined;
            const pagePath = typeof req.query.pagePath === 'string' ? req.query.pagePath : undefined;
            const list = dependencies.list({
                status: STATUSES.includes(status) ? status : undefined,
                relation: RELATIONS.includes(relation) ? relation : undefined,
                pagePath,
            });
            res.json({ dependencies: list, counts: dependencies.counts() });
        }
        catch (err) {
            next(err);
        }
    });
    router.get('/counts', (_req, res, next) => {
        try {
            res.json(dependencies.counts());
        }
        catch (err) {
            next(err);
        }
    });
    router.get('/anchor/:anchor', (req, res, next) => {
        try {
            const result = dependencies.listForAnchor(req.params.anchor);
            res.json(result);
        }
        catch (err) {
            next(err);
        }
    });
    router.post('/', async (req, res, next) => {
        try {
            const body = req.body;
            if (!body.sourceAnchor || !body.targetAnchor || !body.relation) {
                return res
                    .status(400)
                    .json({
                    error: {
                        code: 'VALIDATION',
                        message: 'sourceAnchor, targetAnchor, relation required',
                    },
                });
            }
            if (!RELATIONS.includes(body.relation)) {
                return res
                    .status(400)
                    .json({ error: { code: 'VALIDATION', message: `invalid relation '${body.relation}'` } });
            }
            const dep = dependencies.create({
                sourceAnchor: body.sourceAnchor,
                targetAnchor: body.targetAnchor,
                relation: body.relation,
                description: body.description ?? null,
            });
            try {
                await references.insertSectionRef(dep.sourceAnchor, dep.targetAnchor, dep.relation);
            }
            catch (refErr) {
                console.warn('[dependencies] insertSectionRef failed:', refErr);
            }
            ws.broadcast({ kind: 'dependency:changed', id: dep.id });
            res.status(201).json(dep);
        }
        catch (err) {
            next(err);
        }
    });
    router.delete('/:id', async (req, res, next) => {
        try {
            const id = Number(req.params.id);
            if (!Number.isInteger(id)) {
                return res.status(400).json({ error: { code: 'VALIDATION', message: 'invalid id' } });
            }
            const existing = dependencies.getById(id);
            if (!existing) {
                return res
                    .status(404)
                    .json({ error: { code: 'NOT_FOUND', message: 'dependency not found' } });
            }
            dependencies.remove(id);
            try {
                await references.removeSectionRef(existing.sourceAnchor, existing.targetAnchor, existing.relation);
            }
            catch (refErr) {
                console.warn('[dependencies] removeSectionRef failed:', refErr);
            }
            ws.broadcast({ kind: 'dependency:changed', id });
            res.json({ deleted: true });
        }
        catch (err) {
            next(err);
        }
    });
    router.post('/:id/verify', (req, res, next) => {
        try {
            const id = Number(req.params.id);
            if (!Number.isInteger(id)) {
                return res.status(400).json({ error: { code: 'VALIDATION', message: 'invalid id' } });
            }
            const verified = dependencies.verify(id);
            ws.broadcast({ kind: 'dependency:changed', id });
            res.json(verified);
        }
        catch (err) {
            next(err);
        }
    });
    router.get('/graph', (req, res, next) => {
        try {
            const parseCsv = (raw, allowed) => {
                if (typeof raw !== 'string' || !raw)
                    return undefined;
                const items = raw
                    .split(',')
                    .map((s) => s.trim())
                    .filter(Boolean);
                const filtered = items.filter((i) => allowed.includes(i));
                return filtered.length > 0 ? filtered : undefined;
            };
            const relation = parseCsv(req.query.relation, RELATIONS);
            const status = parseCsv(req.query.status, STATUSES);
            const pagePathPrefix = typeof req.query.pagePathPrefix === 'string' ? req.query.pagePathPrefix : undefined;
            const includeIsolated = req.query.includeIsolated === 'true';
            const graph = dependencies.graph({ relation, status, pagePathPrefix, includeIsolated });
            res.json(graph);
        }
        catch (err) {
            next(err);
        }
    });
    router.get('/impact/:anchor', (req, res, next) => {
        try {
            const result = dependencies.impactAnalysis(req.params.anchor);
            if (!result) {
                return res
                    .status(404)
                    .json({ error: { code: 'NOT_FOUND', message: 'section not found' } });
            }
            res.json(result);
        }
        catch (err) {
            next(err);
        }
    });
    router.use(errorHandler);
    return router;
}
//# sourceMappingURL=dependencies.js.map