import express, { Router, Response, Request } from "express";

import { IReqEx } from "../middlewares/express-auth.mjs";
import { DocServices } from "../services/doc.mjs";
import { Role } from "../db/doc-user-role.mjs";

export function docRouter(services: DocServices) {
    const router = Router();

    router.get('/docs/all', async (req, res) => {
        console.log('docs/all');
        const docs = await services.getAllFiles(currentUserId(req));
        return res.json(docs);
    });

    router.get('/docs/ops/:docId', async (req, res) => {
        console.log('docs/ops', req.params.docId);
        const ops = await services.getOps(req.params.docId);
        return res.json(ops);
    });

    router.get('/docs/history-snapshot/:docId/:version', async (req, res) => {
        console.log('docs/ops', req.params.docId);
        const snapshot = await services.fetchHistorySnapshot(req.params.docId, +req.params.version);
        return res.json(snapshot);
    });
    router.get('/docs/history-snapshot/:docId', async (req, res) => {
        const snapshot = await services.fetchHistorySnapshot(req.params.docId);
        return res.json(snapshot);
    });

    router.get('/docs/:docId', async (req, res) => {
        console.log('docs/docId', req.params.docId);
        const d = await services.get(currentUserId(req), req.params.docId);
        return res.json(d);
    });

    router.get('/docs/delete/:docId', async (req, res) => {
        console.log('docs/docId', req.params.docId);
        const id = await services.delete(currentUserId(req), req.params.docId);

        return res.json({ id });
    });

    router.post('/docs/create', async (req, res) => {
        const { name, type } = req.body;
        const doc = await services.create(currentUserId(req), name, type);

        return res.json(doc);
    });
    router.post('/docs/upload', express.raw({ type: 'application/octet-stream', limit: '100mb' }), // 限制大小为 10MB,
        async (req, res) => {
            const fileBuffer = req.body;
            const file = {
                name: req.headers['x-file-name'],
                type: req.headers['x-file-type'],
                size: fileBuffer.length,
                buffer: fileBuffer,
            };
            const doc = await services.upload(currentUserId(req), file);
            return res.json(doc);
        });
    router.get('/docs/open-share-link/:link', async (req, res) => {
        console.log('open docs share link');
        const link = decodeURIComponent(req.params.link);
        const doc = await services.verifyShareLink(currentUserId(req), link);

        return res.json(doc);
    });

    router.get('/docs/create-share-link/:docId/:role', async (req, res) => {
        const { docId, role } = req.params;
        const link = await services.createShareLink(docId, role as Role);

        return res.json({ link: encodeURIComponent(link) });
    });

    router.get('/docs/users/:docId/', async (req, res) => {
        const { docId } = req.params;
        const users = await services.getUsers(docId);

        return res.json(users);
    });

    router.post('/docs/invite-users', async (req, res) => {
        const { docId, userIds, role } = req.body;
        if (await checkOwnerRole(services, req, res, docId)) {
            return;
        }

        await services.inviteUsers(docId, userIds, role);
        return res.json({});
    });
    router.post('/docs/update-user-role', async (req, res) => {
        const { docId, userId, role } = req.body;
        if (await checkOwnerRole(services, req, res, docId)) {
            return;
        }

        await services.setDocUserRole(docId, userId, role);
        return res.json({});
    });

    router.post('/docs/rename', async (req, res) => {
        const { docId, name } = req.body;
        if (await checkOwnerRole(services, req, res, docId)) {
            return;
        }

        await services.rename(docId, name);
        return res.json({});
    });

    return router;
}

function currentUserId(req: Request) {
    return (req as IReqEx).user.id;
}

async function checkOwnerRole(services: DocServices, req: Request, res: Response, docId: string) {
    const role = await services.getRole(currentUserId(req), docId);
    if (role !== Role.owner) {
        res.status(403).json({ error: "no permission" });
        return true;
    }
    return false;
}

export interface ICreateDocParams {
    type: string;
    createUserId: string;
    name?: string;
    data?: string;
}