import express from "express";
import { requireAuthenticated } from "../middleware/authority.js";
import { needDatabase } from "../middleware/database.js";
import userModel from "../schemas/userModel.js";
import User from "../schemas/userModel.js";
const UserController = express.Router();

UserController.post("/login", needDatabase, async (req, res) => {
    try {
        const email = req.body.email;
        const pwd = req.body.password;
        const user = await User.credentialsExist(email, pwd);
        if (!user) {
            res.sendStatus(401);
            return;
        } else {
            req.session.userId = user._id;
            req.session.email = user.email;
            res.status(200).send("Authenticated.");
        }
    } catch (error) {
        if (error.name === "TypeError") {
            res.status(400).send("Missing required user info.");
        } else if (error.message === "Credentials do not exist.") {
            res.status(401).send("Credentials do not exist.");
        } else {
            console.error(error);
            if (process.env.NODE_ENV === "development") {
                res.status(500).send(error.toString());
            } else {
                res.status(500).send("Internal server error. This issue has been noted.");
            }
        }
    }
});

UserController.get("/logout", requireAuthenticated, (req, res) => {
    req.session.destroy((err) => {
        if (err) {
            console.error(err);
            if (process.env.NODE_ENV === "development") {
                res.status(500).send(err.toString());
            } else {
                res.status(500).send("Internal server error. This issue has been noted.");
            }
            res.status(500).send("");
        } else {
            res.sendStatus(200);
        }
    });
});

UserController.get("/:id?", needDatabase, requireAuthenticated, async (req, res) => {
    let user = null;
    if (req.params.id) {
        if (req.user.accessLevel > 2) {
            user = await userModel.findById(req.params.id);
        } else {
            res.status(401).send("Unauthorized.");
            return;
        }
    } else {
        user = req.user;
    }
    user.password = undefined;
    res.status(200).send(user);
});

UserController.patch("/:id?", needDatabase, requireAuthenticated, async (req, res) => {
    let user = null;
    if (req.params.id) {
        if (req.user.accessLevel > 2) {
            user = await userModel.findById(req.params.id);
        } else {
            res.status(401).send("Unauthorized.");
            return;
        }
    } else {
        user = req.user;
    }
    if (req.body._id) {
        res.status(400).send("Cannot change user ID.");
        return;
    }

    if (req.body.createdMatches) {
        res.status(400).send("Cannot directly change the list of created matches.");
        return;
    }

    if (req.body.password) {
        res.status(400).send("Cannot directly change user password.");
        return;
    }

    if (req.body.participatingMatches) {
        res.status(400).send("Cannot directly change the list of participating matches.");
        return;
    }

    if (req.body.joinDate) {
        res.status(400).send("Cannot change the join date.");
        return;
    }

    if (req.body.accessLevel && req.user.accessLevel < 3) {
        res.status(401).send("Unauthorized to change the access level of this user.");
        return;
    }

    await user.updateOne(req.body);
    res.status(200).send("Updated.");
});

/* TODO: Implement middleware for removing users.

UserController.delete("/:id?", needDatabase, requireAuthenticated, async (req, res) => {
    let user = null;
    if (req.params.id) {
        if (req.user.accessLevel > 2) {
            user = await userModel.findById(req.params.id);
        } else {
            res.status(401).send("Unauthorized.");
            return;
        }
    } else {
        user = req.user;
    }

    await user.deleteOne();
    res.status(200).send("Deleted user.");
});

*/

UserController.post("/", needDatabase, async (req, res) => {
    try {
        let createdUser = new User({
            email: req.body.email,
            firstName: req.body.firstName,
            lastName: req.body.lastName,
            phone: req.body.phone,
            password: req.body.password,
        });
        await createdUser.save();
        res.sendStatus(201);
        return;
    } catch (err) {
        if (err.name === "TypeError" || err.name === "ValidationError") {
            if (process.env.NODE_ENV === "development") {
                console.error(err);
                res.status(400).send(err.toString());
            } else {
                res.status(400).send("Missing required user info.");
            }
        } else if (err.name === "MongoServerError" && err.message.startsWith("E11000")) {
            if (process.env.NODE_ENV === "development") {
                console.error(err);
                res.status(409).send(err.toString());
            } else {
                res.status(409).send("User already exists.");
            }
        } else {
            console.error(err);
            if (process.env.NODE_ENV === "development") {
                res.status(500).send(err.toString());
            } else {
                res.status(500).send("Internal server error. This issue has been noted.");
            }
        }
    }
});

export default UserController;
