import { Request, Response, Router } from "express";
import Stacker from "../middlewares/stacker.js";
import verify, { Types } from "../middlewares/verify.js";
import promiseMiddleware from "../../helper/promiseMiddleware.js";
import User, { Gender } from "../../models/user.js";
import { HttpStatusCode } from "../../helper/request_error.js";
import Mail from "../../models/mail.js";
import RegCode from "../../models/regcodes.js";

const Register = Stacker(
   verify({
      mail: {
         type: Types.EMAIL,
         notempty: true,
      },
      username: {
         type: Types.STRING,
         notempty: true,
      },
      password: {
         type: Types.STRING,
         notempty: true,
      },
      salt: {
         type: Types.STRING,
         notempty: true,
      },
      regcode: {
         type: Types.STRING,
         notempty: true,
      },
      gender: {
         type: Types.STRING,
         notempty: true,
      },
      name: {
         type: Types.STRING,
         notempty: true,
      },
      // birthday: {
      //    type: Types.DATE
      // }
   }),
   promiseMiddleware(async (req: Request, res: Response) => {
      let {
         username,
         password,
         salt,
         mail,
         gender,
         name,
         birthday,
         regcode,
      } = req.body;
      let u = await User.findOne({ username: username.toLowerCase() });
      if (u) {
         let err = {
            message: [
               {
                  message: req.__("Username taken"),
                  field: "username",
               },
            ],
            status: HttpStatusCode.BAD_REQUEST,
            nolog: true,
         };
         throw err;
      }

      let m = await Mail.findOne({ mail: mail });
      if (m) {
         let err = {
            message: [
               {
                  message: req.__("Mail linked with other account"),
                  field: "mail",
               },
            ],
            status: HttpStatusCode.BAD_REQUEST,
            nolog: true,
         };
         throw err;
      }

      let regc = await RegCode.findOne({ token: regcode });
      if (!regc) {
         let err = {
            message: [
               {
                  message: req.__("Invalid registration code"),
                  field: "regcode",
               },
            ],
            status: HttpStatusCode.BAD_REQUEST,
            nolog: true,
         };
         throw err;
      }

      if (!regc.valid) {
         let err = {
            message: [
               {
                  message: req.__("Registration code already used"),
                  field: "regcode",
               },
            ],
            status: HttpStatusCode.BAD_REQUEST,
            nolog: true,
         };
         throw err;
      }

      let g = -1;
      switch (gender) {
         case "male":
            g = Gender.male;
            break;
         case "female":
            g = Gender.female;
            break;
         case "other":
            g = Gender.other;
            break;
         default:
            g = Gender.none;
            break;
      }

      let user = User.new({
         username: username.toLowerCase(),
         password: password,
         salt: salt,
         gender: g,
         name: name,
         // birthday: birthday,
         admin: false,
      });

      regc.valid = false;
      await RegCode.save(regc);

      let ml = Mail.new({
         mail: mail,
         primary: true,
      });

      await Mail.save(ml);

      user.mails.push(ml._id);
      await User.save(user);
      res.json({ success: true });
   })
);
export default Register;
