import log from '../utils/log.js'
import jwt from 'jsonwebtoken';
import config from '../../config.json' with {type: "json"};
import GroupService from '../services/group.js';
import UserService from '../services/user.js';

const TAG = "/middlewares/auth.js";

const requireUsername = async (req, res, next) => {
    if (req.method == "OPTIONS") next();

    try {
        const { username } = req.body;
        if (!username) return res.status(400).send("Username is required");
        next();
    } catch (e) { return res.status(500).send(unknownError(`${TAG}/requireUsername: ${e}`)); }
};

const requirePassword = async (req, res, next) => {
    if (req.method == "OPTIONS") next();

    try {
        const { password } = req.body;
        if (!password) return res.status(400).send("Password is required");
        next();
    } catch (e) { return res.status(500).send(unknownError(`${TAG}/requirePassword: ${e}`)); }
};

const authenticate = async (req, res, next) => {
    if (req.method == "OPTIONS") next();

    try {
        if (!req.headers.authorization) return res.status(403).send("No authorization header supplied");
        const token = req.headers.authorization.split(' ')[1];
        if (!token) return res.status(403).send("No authorization token supplied");
        if (!jwt.verify(token, config.secret)) return res.status(403).send("Authorization token is incorrect");

        next();
    } catch (e) { return res.status(500).send(log.unknownError(`${TAG}/authenticate: ${e}`)); }
};

const authorizeGroupOwner = async (req, res, next) => {
    if (req.method == "OPTIONS") next();

    try {
        const token = req.headers.authorization.split(' ')[1];

        const { groupId } = req.params;

        let user = jwt.decode(token, config.secret);

        let adminId = await GroupService.getAdminId(groupId);
        if (user.login.id != adminId) return res.status(403).send("Not your group");
        next();
    } catch (e) { return res.status(500).send(log.unknownError(`${TAG}/authorizeGroupOwner: ${e}`)); }
};

const checkGroupPassword = async (req, res, next) => {
    if (req.method == "OPTIONS") next();

    try {
        const { groupId } = req.params;
        const { password } = req.body;

        const groupPassword = await GroupService.getPassword(groupId);

        if (groupPassword != password) return res.status(403).send("Wrong password");
        next();

    } catch (e) { return res.status(500).send(log.unknownError(`${TAG}/checkGroupPassword: ${e}`)); }
};

const userIsInGroup = async (req, res, next) => {
    if (req.method == "OPTIONS") next();

    const groupId = req.body.groupId || req.params.groupId;

    const token = req.headers.authorization.split(' ')[1];
    let user = jwt.decode(token, config.secret);
    if (!await UserService.isInGroup(user.login.id, groupId)) return res.status(403).send("You are not a member of this group");
    next();
};

export default {
    requireUsername,
    requirePassword,
    authenticate,
    authorizeGroupOwner,
    checkGroupPassword,
    userIsInGroup
};