const formidable = require("formidable");
const validator = require("validator");
const fs = require("fs");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
const User = require("../models/authModel");
const Kelompok = require("../models/kelompokModel");

class dashboardController {
  dashboardPage = async (req, res) => {
    try {
      const url = `${req.protocol}://${req.get("host")}`;

      const { id } = req.userInfo;
      const userInfo = await User.findById(id);

      const kelompokInfo = await Promise.all(
        JSON.parse(userInfo.code).map(async (code) => {
          const kelompok = await Kelompok.findById(code);
          return kelompok || null;
        })
      ).catch((e) => []);
      const kelompokUser = await Promise.all(
        kelompokInfo.map(async (kelompokInfo) => {
          if (!kelompokInfo) {
            return null;
          }
          const dosen = await User.findById(kelompokInfo.dosen);
          const ketua = await User.findById(kelompokInfo.ketua);
          const anggota = await Promise.all(
            JSON.parse(kelompokInfo.anggota).map((anggotaId) =>
              User.findById(anggotaId)
            )
          );
          return [dosen, ketua, ...anggota];
        })
      );

      const allKelompok = await Kelompok.findByAccKaprodi(1);
      const allKelompokUser = await Promise.all(
        allKelompok.map(async (allKelompok) => {
          if (!allKelompok) {
            return null;
          }
          const dosen = await User.findById(allKelompok.dosen);
          const ketua = await User.findById(allKelompok.ketua);
          const anggota = await Promise.all(
            JSON.parse(allKelompok.anggota).map((anggotaId) =>
              User.findById(anggotaId)
            )
          );
          return [dosen, ketua, ...anggota];
        })
      );

      // console.log(kelompokInfo);
      // console.log(kelompokUser);

      // Dashboard Ketua Kelompok
      if (userInfo.role === "1") {
        const dosen = await User.findByRole("3");
        return res.render("dashboard/dashboardKetua", {
          url,
          userInfo,
          kelompokInfo,
          kelompokUser,
          dosen,
        });

        // Dashboard Anggota Kelompok
      } else if (userInfo.role === "2") {
        return res.render("dashboard/dashboardAnggota", {
          url,
          userInfo,
          kelompokInfo,
          kelompokUser,
        });

        // Dashboard Dosen Pembimbing
      } else if (userInfo.role === "3") {
        const kelompokBimbingan = await Kelompok.findByDospem(
          userInfo.nomor_induk
        );
        return res.render("dashboard/dashboardDospem", {
          url,
          userInfo,
          kelompokInfo,
          kelompokUser,
          kelompokBimbingan,
        });

        // Dashboard Kaprodi
      } else if (userInfo.role === "4") {
        const dosen = await User.findByRole("3");
        const tolakKaprodi = await Kelompok.findByAccKaprodi(0);
        const needAcc = await Kelompok.findByAccKaprodi(null);
        const needAccUser = await Promise.all(
          needAcc.map(async (needAcc) => {
            if (!needAcc) {
              return null;
            }
            const dosen = await User.findById(needAcc.dosen);
            return dosen;
          })
        );

        return res.render("dashboard/dashboardKaprodi", {
          url,
          userInfo,
          needAcc,
          needAccUser,
          allKelompok,
          allKelompokUser,
          dosen,
          tolakKaprodi,
        });

        // Dashboard Dekan dan Wadek
      } else if (userInfo.role === "5") {
        return res.render("dashboard/dashboardDekan", {
          url,
          userInfo,
          allKelompok,
          allKelompokUser,
        });

        // Dashboard Admin Kordinator
      } else if (userInfo.role === "6") {
        const dataUser = await User.find();
        const dataKelompok = await Kelompok.find();
        res.render("dashboard/dashboardAdmin", {
          url,
          userInfo,
          allKelompok,
          allKelompokUser,
          dataUser,
          dataKelompok,
        });
      } else {
        return res.redirect("/logout");
      }
    } catch {
      return res.redirect("/logout");
    }
  };

  editProfile = async (req, res) => {
    const { id } = req.userInfo;
    const userInfo = await User.findById(id);

    const form = formidable({ multiples: true });
    form.parse(req, async (err, fields, files) => {
      const { nim, nama, kelamin, semester, studi, email, telepon, alamat } =
        fields;
      const { foto } = files;

      const user = await User.findById(nim);
      if (user && userInfo.nomor_induk !== nim) {
        return res.render("sweet-alert", {
          icon: "error",
          message: "NIM / NIDN already exist",
          redirectUrl: "/register",
        });
      } else {
        try {
          const editan = await User.findById(userInfo.nomor_induk);
          const code = JSON.parse(userInfo.code);
          const kel = await Kelompok.findById(code[0]);
          if (userInfo.role == "1" && kel) {
            kel.ketua = nim;
            kel.anggota = JSON.parse(kel.anggota);

            await Kelompok.findByIdAndUpdate(code[0], kel);
          }
          if (userInfo.role == "2" && kel) {
            let arr = JSON.parse(kel.anggota);
            let elementToRemove = userInfo.nomor_induk;
            let data = arr.filter((item) => item !== elementToRemove);
            data.push(nim);
            kel.anggota = data;

            await Kelompok.findByIdAndUpdate(code[0], kel);
          }
          if (foto.originalFilename !== "") {
            foto.originalFilename = Date.now() + foto.originalFilename;
            console.log(foto.originalFilename);
            const disPath =
              __dirname + `/../view/assets/foto/${foto.originalFilename}`;
            try {
              await fs.promises.copyFile(foto.filepath, disPath);
              editan.foto = foto.originalFilename;
            } catch (err) {
              return res.render("sweet-alert", {
                icon: "error",
                message: "Upload foto failed please try again",
                redirectUrl: "/dashboard",
              });
            }
          }
          editan.nomor_induk = nim;
          editan.nama = nama;
          editan.jenis_kelamin = kelamin;
          editan.semester = semester;
          editan.program_studi = studi;
          editan.email = email;
          editan.no_telepon = telepon;
          editan.alamat = alamat;
          editan.code = JSON.parse(editan.code);
          await User.findByIdAndUpdate(userInfo.nomor_induk, editan);

          res.clearCookie("curdToken");
          const token = jwt.sign(
            {
              id: nim,
            },
            "affidev",
            {
              expiresIn: "3d",
            }
          );

          res.cookie("curdToken", token, {
            expires: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000),
          });

          return res.render("sweet-alert", {
            icon: "success",
            message: "Your edit successfull",
            redirectUrl: "/dashboard",
          });
        } catch {
          return res.render("sweet-alert", {
            icon: "error",
            message: "Your edit failed",
            redirectUrl: "/dashboard",
          });
        }
      }
    });
  };

  editPassword = async (req, res) => {
    try {
      const { id } = req.userInfo;
      const userInfo = await User.findById(id);
      const form = formidable({ multiples: true });
      form.parse(req, async (err, fields, files) => {
        const { passwordlama, passwordbaru, passwordbarufix } = fields;
        if (passwordbaru !== passwordbarufix) {
          return res.render("sweet-alert", {
            icon: "error",
            message: "New passwords do not match",
            redirectUrl: "/dashboard",
          });
        }
        const user = await User.findById(userInfo.nomor_induk);
        const isValid = await bcrypt.compare(passwordlama, user.password);
        if (!isValid) {
          return res.render("sweet-alert", {
            icon: "error",
            message: "Invalid current password",
            redirectUrl: "/dashboard",
          });
        }
        const hashedPassword = await bcrypt.hash(passwordbaru, 9);
        user.password = hashedPassword;
        user.code = JSON.parse(user.code);
        await User.findByIdAndUpdate(userInfo.nomor_induk, user);
        return res.render("sweet-alert", {
          icon: "success",
          message: "Password updated successfully",
          redirectUrl: "/dashboard",
        });
      });
    } catch (err) {
      console.error(err);
      return res.render("sweet-alert", {
        icon: "error",
        message: "Internal Server Error",
        redirectUrl: "/dashboard",
      });
    }
  };
}

module.exports = new dashboardController();
