const User = require("../../models").users;
const Profile = require("../../models").profiles;
const Project = require("../../models").projects;
const ProjectSubmission = require("../../models").project_submissions;
const StudentSupervisor = require("../../models").student_supervisors;
const ProjectTopic = require("../../models").project_topics;
const Packages = require("../../models").packages;
const Subcriptions = require("../../models").subscriptions;
const Siwes = require("../../models").siwes;
const Department = require("../../models").departments;
const Institute = require("../../models").institutes;
const Study_modes = require("../../models").study_modes;
const PaystackDetails = require("../../models").paystack_details;
const Bindingpayment = require("../../models").binding_payments;
const paymentHistory = require("../../models").payment_history;
const ProjectType = require("../../models").project_types;
const DocumentCategory = require("../../models").document_categories;
const Activity = require("../helpers/activity.helper");
const SchoolSessions = require("../../models").sessions;
const { Op, where } = require("sequelize");
const qr = require("qrcode");
const { GoogleAuth } = require("google-auth-library");
const { google } = require("googleapis");
const fs = require("fs");
const mime = require("mime");
const { verifyPayment } = require("./paystack-transaction-init.controller");
const pathLib = require("path");
const readline = require("readline");

const TOKEN_PATH = pathLib.join(__dirname, "token.json");
const CREDENTIALS_PATH = pathLib.join(__dirname, "credentials.json"); 
const SCOPES = ["https://www.googleapis.com/auth/drive.file"]; 

async function authorize() {
  const credentials = JSON.parse(fs.readFileSync(CREDENTIALS_PATH, "utf8"));
  const { client_secret, client_id, redirect_uris } = credentials.web;

  const oAuth2Client = new google.auth.OAuth2(
    client_id,
    client_secret,
    redirect_uris[0]
  );

  // If we already have a token, use it
  if (fs.existsSync(TOKEN_PATH)) {
    let token = JSON.parse(fs.readFileSync(TOKEN_PATH, "utf8"));
    oAuth2Client.setCredentials(token);

    // Check if token has expired
    if (token.expiry_date && Date.now() >= token.expiry_date) {
      console.log("Access token expired, refreshing...");
      const newTokens = await oAuth2Client.refreshAccessToken();
      token = { ...token, ...newTokens.credentials };
      fs.writeFileSync(TOKEN_PATH, JSON.stringify(token));
      oAuth2Client.setCredentials(token);
      console.log("Token refreshed and saved.");
    }

    return oAuth2Client;
  }

  // No token yet → start auth flow
  const authUrl = oAuth2Client.generateAuthUrl({
    access_type: "offline",
    scope: SCOPES,
  });
  console.log("Authorize this app by visiting:", authUrl);

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  const code = await new Promise((resolve) => {
    rl.question("Enter the code from that page here: ", (input) => {
      rl.close();
      resolve(input);
    });
  });

  const { tokens } = await oAuth2Client.getToken(code);
  oAuth2Client.setCredentials(tokens);
  fs.writeFileSync(TOKEN_PATH, JSON.stringify(tokens));
  console.log("Token stored to", TOKEN_PATH);

  return oAuth2Client;
}

exports.studentDashboard = async (req, res) => {
  try {
    if (req.user.first_login == false)
      return res.redirect(
        "/user/get-started?corass-pro-d=" +
          req.user.id +
          "&id=" +
          req.user.username
      );

    if (
      !req.profile.study_mode_id ||
      !req.profile.department_id ||
      !req.profile.level_id
    ) {
      return res.redirect(`/user/new-record?id=${req.user.username}`);
    }
    let pendingProj = 0;
    let approvedProj = 0;
    let rejectedProj = 0;
    let allSubProject = [];
    let allTopic = [];
    let isReady = false;
    let project = {};
    const myTopic = await ProjectTopic.findOne({
      where: {
        student_user_id: req.user.id,
        active: true,
        is_approved: true,
      },
      raw: true,
    });

    if (myTopic) {
      allSubProject = await ProjectSubmission.findAll({
        where: {
          project_id: myTopic.id,
        },
      });
      pendingProj = await ProjectSubmission.count({
        where: {
          active: true,
          project_id: myTopic.id,
          is_approved: false,
        },
      });
      approvedProj = await ProjectSubmission.count({
        where: {
          active: true,
          project_id: myTopic.id,
          is_approved: true,
        },
      });
      rejectedProj = await ProjectSubmission.count({
        where: {
          active: false,
          project_id: myTopic.id,
        },
      });
    }
    const myProfile = await Profile.findOne({
      where: {
        user_id: req.user.id,
      },
      raw: true,
    });
    const supervisoDetailsStudentSupervisor = await StudentSupervisor.findOne({
      where: {
        student_user_id: req.user.id,
      },
    });
    let supervisoDetails = {};
    if (supervisoDetailsStudentSupervisor) {
      supervisoDetails = await Profile.findOne({
        where: {
          user_id: JSON.parse(JSON.stringify(supervisoDetailsStudentSupervisor))
            .lecturer_user_id,
        },
      });
    }

    const topicApproved = await ProjectTopic.count({
      where: {
        active: true,
        student_user_id: req.user.id,
        is_approved: true,
      },
    });
    const topics = await ProjectTopic.findAll({
      where: {
        active: true,
        student_user_id: req.user.id,
      },
    });
    for (let singleTopic of JSON.parse(JSON.stringify(topics))) {
      if (singleTopic.lecturer_user_id) {
        const lecturer = await Profile.findOne({
          where: {
            user_id: singleTopic.lecturer_user_id,
          },
        });
        allTopic.push({
          ...singleTopic,
          lecturer,
        });
      }
    }
    const approveTopic = await ProjectTopic.findOne({
      where: {
        is_approved: true,
        active: true,
        student_user_id: req.user.id,
      },
      raw: true,
    });
    if (approveTopic) {
      project = await ProjectSubmission.findOne({
        where: {
          document_category_id: 7,
          project_id: approveTopic.id,
          is_approved: true,
          active: true,
        },
        raw: true,
      });

      if (project) isReady = true;
    }
    // console.log(req.user)
    return res.render("student/student_dashboard.ejs", {
      user: req.user,
      profile: JSON.parse(JSON.stringify(req.user)),
      error: false,
      pendingProj,
      approvedProj,
      rejectedProj,
      allDoc: JSON.parse(JSON.stringify(allSubProject)).length,
      topics: JSON.parse(JSON.stringify(allTopic)),
      supervisoDetails: JSON.parse(JSON.stringify(supervisoDetails)),
      topicApproved,
      subscriptions: req.subscriptions,
      isReady,
      project,
    });

    // just solve xonflict
  } catch (error) {
    console.log(error);
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
  }
};
exports.studentProjectBindingDashboard = async (req, res) => {
  try {
    let pendingProj = 0;
    let approvedProj = 0;
    let rejectedProj = 0;
    let allSubProject = [];
    let allTopic = [];

    const { trxref } = req.query;

    if (trxref) await verifyPayment(trxref);

    const allProjects = await Project.findAll({
      where: {
        active: true,
        student_user_id: req.user.id,
      },
    });
    const bindingPayment = await Bindingpayment.findOne({
      where: { user_id: req.user.id, txn_status: "success" },
    });
    for (const project of allProjects) {
      const getsubProj = await ProjectSubmission.findAll({
        where: {
          project_id: project.id,
        },
      });
      allSubProject = [...allSubProject, getsubProj];
    }
    for (const subProj of allSubProject) {
      if (subProj[0]?.is_approved == false) {
        pendingProj++;
      }
      if (subProj[0]?.is_approved == true) {
        approvedProj++;
      }
      if (subProj[0]?.active == false) {
        rejectedProj++;
      }
    }
    const myProfile = await Profile.findOne({
      where: {
        user_id: req.user.id,
      },
    });
    const supervisoDetailsStudentSupervisor = await StudentSupervisor.findOne({
      where: {
        student_user_id: req.user.id,
      },
      raw: true,
    });
    let supervisoDetails = {};
    if (supervisoDetailsStudentSupervisor) {
      supervisoDetails = await Profile.findOne({
        where: {
          user_id: supervisoDetailsStudentSupervisor?.lecturer_user_id,
        },
      });
    }

    const topicApproved = await ProjectTopic.count({
      where: {
        active: true,
        student_user_id: req.user.id,
        is_approved: true,
      },
    });
    const topics = await ProjectTopic.findAll({
      where: {
        active: true,
        student_user_id: req.user.id,
      },
    });
    for (let singleTopic of JSON.parse(JSON.stringify(topics))) {
      const lecturer = await Profile.findOne({
        where: {
          user_id: singleTopic.lecturer_user_id,
        },
      });
      allTopic.push({
        ...singleTopic,
        lecturer,
      });
    }
    let bindingPogress = 0;
    if (bindingPayment?.status == "PAID") {
      bindingPogress = 30;
    } else if (bindingPayment?.status == "SUBMITTED") {
      bindingPogress = 60;
    } else if (bindingPayment?.status == "READY") {
      bindingPogress = 100;
    }
    return res.render("student/student_project_binding.ejs", {
      user: req.user,
      profile: JSON.parse(JSON.stringify(myProfile)),
      error: false,
      pendingProj,
      approvedProj,
      rejectedProj,
      allDoc: JSON.parse(JSON.stringify(allSubProject)).length,
      topics: JSON.parse(JSON.stringify(allTopic)),
      supervisoDetails: JSON.parse(JSON.stringify(supervisoDetails)),
      topicApproved,
      subscriptions: req.subscriptions,
      bindingPayment,
      paidForBinding: bindingPayment?.txn_status == "success" ? true : false,
      bindingPogress,
    });

    // just solve xonflict
  } catch (error) {
    console.log(error);
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
    // return res.render("student/student_project_binding.ejs", {
    //   user: req.user,
    //   error: error.message,
    //   pendingProj: 0,
    //   profile: {},
    //   topicApproved: 0,
    //   approvedProj: 0,
    //   rejectedProj: 0,
    //   allDoc: 0,
    //   topics: [],
    //   supervisoDetails: {},
    //   subscriptions: req.subscriptions,
    //   bindingPayment: 0,
    //   paidForBinding: 0 ? true : false,
    //   bindingPogress: 0,
    // });
  }
};

exports.paymentPlan = async (req, res) => {
  try {
    if (req.user.first_login == false)
      return res.redirect(
        "/user/get-started?corass-pro-d=" +
          req.user.id +
          "&id=" +
          req.user.username
      );

    var userSubcription = await Subcriptions.findAll({
      attributes: ["pakage_id"],
      where: {
        active: 1,
        user_id: req.user.id,
      },
    });

    var finalSubcription;
    var PaymentPlan;
    var finalPackages;

    if (userSubcription.length > 0) {
      var arraySub = [];
      for (var userSubcriptions of userSubcription) {
        arraySub.push(userSubcriptions.pakage_id);
      }

      finalSubcription = await Packages.findAll({
        where: {
          active: 1,
          id: arraySub,
        },
      });

      PaymentPlan = await Packages.findAll({
        where: {
          active: 1,
          [Op.not]: [
            {
              id: arraySub,
            },
          ],
        },
      });

      var arrayPlans = [];
      for (var PaymentPlans of PaymentPlan) {
        arrayPlans.push(PaymentPlans.id);
      }

      finalPackages = await Packages.findAll({
        where: {
          active: 1,
          id: arrayPlans,
        },
      });
    } else {
      finalPackages = await Packages.findAll({
        where: {
          active: 1,
        },
      });
      finalSubcription = undefined;
    }

    return res.render("student/payments_plan.ejs", {
      user: req.user,
      subscriptions: req.subscriptions,
      profile: req.profile,
      PaymentPlan: finalPackages,
      finalSubcription,
    });
  } catch (error) {
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
  }
};

exports.payment = async (req, res) => {
  try {
    const paystackKey = await PaystackDetails.findAll();
    const paystack = require("paystack")(paystackKey[0].LIVE_SECRET_KEY);
    // const paystack = require("paystack")(paystackKey[0].TEST_SECRET_KEY);
    const paystackReference = req.query.reference;

    if (req.user.first_login == false)
      return res.redirect(
        "/user/get-started?corass-pro-d=" +
          req.user.id +
          "&id=" +
          req.user.username
      );

    var paystackCallbackStatus;
    if (paystackReference != undefined) {
      await paystack.transaction
        .verify(paystackReference)
        .then((transaction) => {
          paystackCallbackStatus = transaction.data.status;
        });
    }

    if (paystackReference === "") {
      paystackCallbackStatus = undefined;
    }
    const binding_payments = await Bindingpayment.findAll({
      order: [["createdAt", "DESC"]],
      where: {
        user_id: req.user.id,
      },
    });
    var getPayemtHistory = await paymentHistory.findAll({
      order: [["createdAt", "DESC"]],
      where: {
        username: req.user.username,
      },
    });

    var eachPakages = [];

    for (const getPayemtHistories of JSON.parse(
      JSON.stringify(getPayemtHistory)
    )) {
      const GetPackages = await Packages.findOne({
        where: {
          id: getPayemtHistories.package_id,
        },
      });
      eachPakages.push({
        ...getPayemtHistories,
        package_name: GetPackages?.name,
      });
    }

    return res.render("student/payments.ejs", {
      user: req.user,
      subscriptions: req.subscriptions,
      trxStatus: paystackCallbackStatus,
      error: {
        statusCode: "500",
        success: false,
        message: "Error",
        error: undefined,
      },
      getPayemtHistory: eachPakages,
      success: {
        statusCode: "200",
        success: false,
        message: paystackCallbackStatus,
      },
      binding_payments,
    });
  } catch (error) {
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
  }
};

exports.verifyPayment = async (req, res) => {
  try {
    const paystackKey = await PaystackDetails.findAll();
    const paystack = require("paystack")(paystackKey[0].LIVE_SECRET_KEY);
    // const paystack = require("paystack")(paystackKey[0].TEST_SECRET_KEY);
    const paystackReference = req.body.reference;

    if (!paystackReference) {
      return res.status(200).send({
        statusCode: "401",
        success: false,
        message: "Error",
        error: "Payment reference is required",
      });
    }

    var paystackCallbackRes;
    const verifyPay = await paystack.transaction
      .verify(paystackReference)
      .then((transaction) => {
        paystackCallbackRes = transaction.data;
      });

    if (paystackCallbackRes?.status != undefined) {
      var findSUb = await Subcriptions.findOne({
        where: {
          payment_id: paystackCallbackRes.reference,
        },
      });
      if (paystackCallbackRes.status === "success" && findSUb === null) {
        const findPaymentHistory = await paymentHistory.findOne({
          where: {
            txn_ref: paystackCallbackRes.reference,
            username: paystackCallbackRes.metadata.matricNumber,
          },
        });

        const updateUser = {
          payment_status: "PAID",
        };
        const updatePaid = await User.update(updateUser, {
          where: {
            username: paystackCallbackRes.metadata.matricNumber,
          },
        });

        const createSub = await Subcriptions.create({
          user_id: req.user.id,
          payment_id: paystackCallbackRes.reference,
          pakage_id: findPaymentHistory.package_id,
        });

        const updatePayment = {
          txn_desc: paystackCallbackRes.gateway_response,
          txn_status: paystackCallbackRes.status,
          txn_channel: paystackCallbackRes.channel,
        };

        const updateHistory = await paymentHistory.update(updatePayment, {
          where: {
            txn_ref: paystackCallbackRes.reference,
            username: paystackCallbackRes.metadata.matricNumber,
          },
        });

        if (updateHistory && createSub && updatePaid) {
          return res.status(200).send({
            statusCode: "200",
            success: true,
            message: paystackCallbackRes.gateway_response,
          });
        }
      } else {
        const updatePayment = {
          txn_desc: paystackCallbackRes.gateway_response,
          txn_status: paystackCallbackRes.status,
          txn_channel: paystackCallbackRes.channel,
        };

        const updateHistory = await paymentHistory.update(updatePayment, {
          where: {
            txn_ref: paystackCallbackRes.reference,
            username: paystackCallbackRes.metadata.matricNumber,
          },
        });

        if (updateHistory) {
          return res.status(200).send({
            statusCode: "200",
            success: true,
            message: paystackCallbackRes.gateway_response,
          });
        }
      }
    }
  } catch (e) {
    console.log(e);
    res.status(500).send({
      statusCode: "500",
      success: false,
      message: "Error",
      error: e.message,
    });
  }
};

exports.projectSubmission = async (req, res) => {
  if (!req.user.first_login) {
    return res.redirect(
      `/user/get-started?corass-pro-d=${req.user.id}&id=${req.user.username}`
    );
  }
  if (req.user.profile.session.status == false) {
    return res.redirect(`/student-dashboard`);
  }
  try {
    const [topic, topics, supervisor] = await Promise.all([
      ProjectTopic.findOne({
        where: {
          student_user_id: req.user.id,
          active: true,
          is_approved: true,
        },
      }),
      ProjectTopic.findOne({
        where: {
          student_user_id: req.user.id,
          active: true,
          is_approved: true,
        },
        include: [
          {
            model: ProjectSubmission,
            include: [
              { model: DocumentCategory, attributes: ["name"] },
              {
                model: ProjectTopic,
                include: [
                  {
                    model: User,
                    as: "lecturer",
                    attributes: ["username"],
                    include: [
                      {
                        model: Profile,
                        attributes: ["firstname", "lastname", "middlename"],
                      },
                    ],
                  },
                ],
              },
            ],
          },
        ],
      }),
      StudentSupervisor.findOne({
        where: { student_user_id: req.user.id, active: true },
        include: [
          {
            model: User,
            as: "lecturer",
            include: [{ model: Profile }],
          },
        ],
      }),
    ]);

    return res.render("student/project_submission.ejs", {
      user: req.user,
      subscriptions: req.subscriptions,
      topics,
      topic,
      supervisor: JSON.parse(JSON.stringify(supervisor)),
    });
  } catch (error) {
    console.error("Error in projectSubmission:", error);
    // Handle the error appropriately (e.g., send an error response or render an error page)
    return res.status(500).send("An error occurred.");
  }
};
exports.projectSubmissionFull = async (req, res) => {
  if (!req.user.first_login) {
    return res.redirect(
      `/user/get-started?corass-pro-d=${req.user.id}&id=${req.user.username}`
    );
  }
  if (req.user.profile.session.status == false) {
    return res.redirect(`/student-dashboard`);
  }
  try {
    const [topic, topics, supervisor] = await Promise.all([
      ProjectTopic.findOne({
        where: {
          student_user_id: req.user.id,
          active: true,
          is_approved: true,
        },
        raw:true
      }),
      ProjectTopic.findOne({
        where: {
          student_user_id: req.user.id,
          active: true,
          is_approved: true,
        },
        include: [
          {
            model: ProjectSubmission,
            where:{document_category_id: 8},
            required:true,
            include: [
              { model: DocumentCategory, attributes: ["name"] },
              {
                model: ProjectTopic,
                include: [
                  {
                    model: User,
                    as: "lecturer",
                    attributes: ["username"],
                    include: [
                      {
                        model: Profile,
                        attributes: ["firstname", "lastname", "middlename"],
                      },
                    ],
                  },
                ],
              },
            ],
          },
        ],
      }),
      StudentSupervisor.findOne({
        where: { student_user_id: req.user.id, active: true },
        include: [
          {
            model: User,
            as: "lecturer",
            include: [{ model: Profile }],
          },
        ],
      }),
    ]);
    return res.render("student/print_project_submission.ejs", {
      user: req.user,
      subscriptions: req.subscriptions,
      topics,
      topic,
      supervisor: JSON.parse(JSON.stringify(supervisor)),
    });
  } catch (error) {
    console.error("Error in projectSubmission:", error);
    // Handle the error appropriately (e.g., send an error response or render an error page)
    return res.status(500).send("An error occurred.");
  }
};

exports.project = (req, res) => {
  try {
    if (req.user.first_login == false)
      return res.redirect(
        "/user/get-started?corass-pro-d=" +
          req.user.id +
          "&id=" +
          req.user.username
      );
    if (req.user.profile.session.status == false) {
      return res.redirect(`/student-dashboard`);
    }
    return res.render("student/student_project.ejs", {
      user: req.user,
      subscriptions: req.subscriptions,
    });
  } catch (error) {
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
  }
};

exports.siwes = async (req, res) => {
  if (req.user.first_login == false)
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
  if (req.user.profile.session.status == false) {
    return res.redirect(`/student-dashboard`);
  }
  try {
    let supervisor = await StudentSupervisor.findOne({
      where: { student_user_id: req.user.id, active: true, project_type_id: 4 },
      include: [
        {
          model: User,
          as: "lecturer",
          include: [{ model: Profile }],
        },
      ],
    });
    const projects = await Siwes.findAll({
      where: {
        active: 1,
        student_user_id: req.user.id,
      },
    });
    return res.render("student/student_siwes.ejs", {
      user: req.user,
      subscriptions: req.subscriptions,
      projects,
      supervisor,
    });
  } catch (e) {
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
  }
};

exports.topicSubmission = async (req, res) => {
  if (req.user.first_login == false)
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
  if (req.user.profile.session.status == false) {
    return res.redirect(`/student-dashboard`);
  }

  try {
    const allTopic = [];
    const topics = await ProjectTopic.findAll({
      where: {
        student_user_id: req.user.id,
      },
      include: [
        {
          model: ProjectType,
        },
      ],
    });
    const supervisoDetailsStudentSupervisor = await StudentSupervisor.findOne({
      where: {
        student_user_id: req.user.id,
      },
    });
    let supervisoDetails = {};
    if (supervisoDetailsStudentSupervisor) {
      supervisoDetails = await Profile.findOne({
        where: {
          user_id: JSON.parse(JSON.stringify(supervisoDetailsStudentSupervisor))
            .lecturer_user_id,
        },
      });
    }

    for (let singleTopic of JSON.parse(JSON.stringify(topics))) {
      let lecturer = {};
      if (singleTopic.lecturer_user_id) {
        lecturer = await Profile.findOne({
          where: {
            user_id: singleTopic.lecturer_user_id,
          },
        });
      }
      allTopic.push({
        ...singleTopic,
        lecturer,
      });
    }
    return res.render("student/topic_submission.ejs", {
      user: req.user,
      subscriptions: req.subscriptions,
      ProjectTopicData: allTopic,
      supervisoDetails,
    });
  } catch (e) {
    console.log(e);
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
  }
};

exports.acknownledge = async (req, res) => {
  if (req.user.first_login == false)
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
  const project = await ProjectTopic.findOne({
    where: { student_user_id: req.user.id, active: true, is_approved: true },
    include: [
      {
        model: ProjectSubmission,
        require: true,
        where: { document_category_id: 7 },
        include: [
          {
            model: DocumentCategory,
            attributes: ["name"],
          },
          {
            model: ProjectTopic,
            include: [
              {
                model: User,
                as: "lecturer",
                attributes: ["username"],
                include: [
                  {
                    model: Profile,
                    attributes: ["firstname", "lastname", "middlename"],
                  },
                ],
              },
            ],
          },
        ],
      },
    ],
  });
  if (!project) return res.redirect("/student-dashboard");
  return res.render("student/note.ejs", {
    user: req.user,
    subscriptions: req.subscriptions,
    project,
  });
};

exports.receipt = async (req, res) => {
  try {
    // if (req.user.first_login == false)
    //   return res.redirect(
    //     "/user/get-started?corass-pro-d=" +
    //       req.user.id +
    //       "&id=" +
    //       req.user.username
    //   );

    const txnReference = req.query.reference;
    const username = req.query.MatricNo;

    const user = await User.findOne({
      where: {
        username: username,
      },
      raw:true
    });
    const profile = await Profile.findOne({
      where:{user_id:user.id},
      include:[
        {
          model: User,
          attributes: ["username"],
        },
        {
          model: Study_modes,
          attributes: ["name"],
        },
        {
          model: Department,
          attributes: ["id", "name"],
          include: [
            {
              model: Institute,
              attributes: ["name"],
            },
          ],
        },
      ]
    })
    const MypaymentHistory = await paymentHistory.findOne({
      where: {
        id: txnReference,
      },
    });

    const GetPackages = await Packages.findOne({
      where: {
        id: MypaymentHistory?.package_id,
      },
    });

    const GetSession = await SchoolSessions.findAll({});

    const url = req.headers.host + req.url;
    qr.toDataURL(url, (err, src) => {
      if (err) res.send("Error occured");
      console.log(user)
      return res.render("receipt.ejs", {
        user,
        MypaymentHistory,
        subscriptions: req.subscriptions,
        profile: profile,
        Sessions: GetSession[0].name,
        src,
        GetPackages,
      });
    });
  } catch (error) {
    console.log(error)
    return res.redirect(
      "/user/get-started?corass-pro-d=" +
        req.user.id +
        "&id=" +
        req.user.username
    );
  }
};

exports.projectUpload = async (req, res) => {
  try {
    const { project_id, document_category_id, description } = req.body;

    if (!document_category_id) {
      return res.status(409).send({
        statusCode: "409",
        success: false,
        message: "Error",
        error: "Document Category is required",
      });
    }

    if (!req.file) {
      return res.status(400).send("Please upload a valid file!");
    }

    const path = req.file.filename;
    const filePath = `./project/${path}`;

    if (!fs.existsSync(filePath)) {
      return res.status(400).send("File not found!");
    }

    // Authorize via OAuth2
    const auth = await authorize();
    const drive = google.drive({ version: "v3", auth });

    // Your folder ID in personal Google Drive
    const FOLDER_ID = "1WT9ovA5S2EeLimX8o9b9cC6YFMCLfvFJ";

    const fileMetadata = {
      name: path,
      parents: [FOLDER_ID],
    };

    const media = {
      mimeType: mime.getType(filePath) || "application/octet-stream",
      body: fs.createReadStream(filePath),
    };

    const file = await drive.files.create({
      resource: fileMetadata,
      media,
      fields: "id",
    });

    const mainId = file.data.id;

    // Make file public
    await drive.permissions.create({
      fileId: mainId,
      sendNotificationEmail: false,
      resource: {
        type: "anyone",
        role: "writer", // safer than writer for public access
      },
    });

    // Save to DB
    let session_id = "";
    const session = await SchoolSessions.findOne({ where: { status: true } });
    if (session) session_id = session.id;

    await ProjectSubmission.create({
      project_id,
      document_category_id,
      description,
      document_path: path,
      is_approved: false,
      slug: mainId,
      session_id,
    });

    await Activity("Project Submission", `${req.user.username} submit research document`, topic.lecturer_user_id);
    await Activity("Project Submission", `You submit research document`, topic.student_user_id);
    return res.status(200).send({
      success: true,
      message: "Project successfully created",
    });
  } catch (e) {
    console.error("Error details:", e);
    res.status(500).send({
      statusCode: "500",
      success: false,
      message: "Error",
      error: e.message,
    });
  }
};
exports.finalProjectUpload = async (req, res) => {
  try {
    const { project_id, document_category_id, description } = req.body;

    if (!document_category_id) {
      return res.status(409).send({
        statusCode: "409",
        success: false,
        message: "Error",
        error: "Document Category is required",
      });
    }

    if (!req.file) {
      return res.status(400).send("Please upload a valid file!");
    }

    const path = req.file.filename;
    const filePath = `./project/final/${path}`;

    if (!fs.existsSync(filePath)) {
      return res.status(400).send("File not found!");
    }

    // Authorize via OAuth2
    const auth = await authorize();
    const drive = google.drive({ version: "v3", auth });

    // Your folder ID in personal Google Drive
    const FOLDER_ID = "1jgS6DkD43WyMtmMW0qM1AIngy_8dqGFU";

    const fileMetadata = {
      name: path,
      parents: [FOLDER_ID],
    };

    const media = {
      mimeType: mime.getType(filePath) || "application/octet-stream",
      body: fs.createReadStream(filePath),
    };

    const file = await drive.files.create({
      resource: fileMetadata,
      media,
      fields: "id",
    });

    const mainId = file.data.id;

    // Make file public
    await drive.permissions.create({
      fileId: mainId,
      sendNotificationEmail: false,
      resource: {
        type: "anyone",
        role: "reader", // safer than writer for public access
      },
    });

    // Save to DB
    let session_id = "";
    const session = await SchoolSessions.findOne({ where: { status: true } });
    if (session) session_id = session.id;

    await ProjectSubmission.create({
      project_id,
      document_category_id,
      description,
      document_path: path,
      is_approved: false,
      slug: mainId,
      session_id,
    });

    await Activity("Project Submission", `${req.user.username} submit research document`, topic.lecturer_user_id);
    await Activity("Project Submission", `You submit research document`, topic.student_user_id);
    return res.status(200).send({
      success: true,
      message: "Project successfully created",
    });
  } catch (e) {
    console.error("Error details:", e);
    res.status(500).send({
      statusCode: "500",
      success: false,
      message: "Error",
      error: e.message,
    });
  }
};

exports.finalPrintProjectUpload = async (req, res) => {
  try {
    const { project_id, document_category_id, description, receipt_number } = req.body;

    if (!document_category_id) {
      return res.status(409).send({
        statusCode: "409",
        success: false,
        message: "Error",
        error: "Document Category is required",
      });
    }

    if (req.file == undefined) {
      return res.status(400).send("Please upload a valid file!");
    }

    let path = req.file.filename;
    let mainId = "";

    const auth = new GoogleAuth({
      keyFile: __dirname + "/corass-project-20725bec603b.json",
      scopes: ["https://www.googleapis.com/auth/drive"],
    });

    const client = await auth.getClient();
    const drive = google.drive({ version: "v3", auth: client });

    const fileMetadata = {
      name: path,
      mimeType: "application/vnd.google-apps.document",
    };

    const media = {
      mimeType: mime.getType("./project/final/" + path),
      body: fs.createReadStream("./project/final/" + path),
    };

    drive.files.create(
      {
        resource: fileMetadata,
        media: media,
        fields: "id",
      },
      async (err, file) => {
        if (err) {
          console.error(err);
          return;
        }

        mainId = file.data.id;

        const permission = {
          type: "anyone",
          role: "writer",
          allowFileDiscovery: true,
        };

        drive.permissions.create(
          {
            fileId: mainId,
            sendNotificationEmail: false,
            resource: permission,
          },
          async (err, resPerm) => {
            if (err) {
              console.error(err);
              return;
            }
            // Remove existing record before creating a new one
            await ProjectSubmission.destroy({
              where: {
                project_id,
                document_category_id,
              },
            });

            let session_id = "";
            const session = await SchoolSessions.findOne({
              where: { status: true },
            });

            if (session) {
              session_id = session.id;
            }

            await ProjectSubmission.create({
              project_id,
              document_category_id:7,
              description,
              document_path: path,
              is_approved: false,
              slug: mainId,
              session_id,
              ppo_id:req.user.ppo_id
            });

            await Profile.update(
              { receipt_number },
              { where: { user_id: req?.user?.id } }
            );

            return res.status(200).send({
              success: true,
              message: "Project successfully created",
            });
          }
        );
      }
    );
  } catch (e) {
    console.log(e);
    res.status(500).send({
      statusCode: "500",
      success: false,
      message: "Error",
      error: e.message,
    });
  }
};

exports.deleteProject = async (req, res) => {
  const { id } = req.params;
  await ProjectSubmission.destroy({
    where: {
      id,
    },
  });
  return res.redirect("/project-submission");
};
exports.siwesUpload = async (req, res) => {
  try {
    const { title, description } = req.body;

    if (!title) {
      return res.status(409).send({
        statusCode: "409",
        success: false,
        message: "Error",
        error: "Title is required",
      });
    }

    if (req.file == undefined) {
      return res.status(400).send("Please upload a valid file!");
    }
    let path = req.file.filename;
    let mainId = "";
    const auth = new GoogleAuth({
      keyFile: __dirname + "/corass-project-20725bec603b.json",
      scopes: ["https://www.googleapis.com/auth/drive"],
    });
    const client = await auth.getClient();

    const drive = google.drive({ version: "v3", auth: client });

    const fileMetadata = {
      name: path,
      mimeType: "application/vnd.google-apps.document",
    };

    const media = {
      mimeType: mime.getType("./project/" + path),
      body: fs.createReadStream("./project/" + path),
    };
    drive.files.create(
      {
        resource: fileMetadata,
        media: media,
        fields: "id",
      },
      async (err, file) => {
        if (err) {
          // Handle the error
          console.error(err);
          return;
        }
        mainId = file.data.id;
        console.log(`File ID: ${file.data.id}`);
        const permission = {
          type: "anyone",
          role: "writer",
          allowFileDiscovery: true,
        };
        drive.permissions.create(
          {
            fileId: mainId,
            sendNotificationEmail: false,
            resource: permission,
          },
          async (err, res) => {
            if (err) {
              // Handle the error
              console.error(err);
              return;
            }
            const project = await Siwes.create({
              title,
              student_user_id: req.user.id,
              description,
              document_path: path,
              is_approved: false,
              slug: mainId,
              active: true,
            });
          }
        );
      }
    );
    return res.status(200).send({
      success: true,
    });
  } catch (e) {
    console.log(e);
    res.status(500).send({
      statusCode: "500",
      success: false,
      message: "Error",
      error: e.message,
    });
  }
};
exports.deleteSiwes = async (req, res) => {
  const { id } = req.params;
  await Siwes.destroy({
    where: {
      id,
    },
  });
  return res.redirect("/siwes");
};
exports.renderPdf = async (req, res) => {
  try {
    let mainId = "";
    const auth = new GoogleAuth({
      keyFile: __dirname + "/the-dominion-373722-c31c55ca8ca1.json",
      scopes: ["https://www.googleapis.com/auth/drive"],
    });
    const client = await auth.getClient();

    const drive = google.drive({ version: "v3", auth: client });

    const fileMetadata = {
      name: "My Google Doc",
      mimeType: "application/vnd.google-apps.document",
    };

    const media = {
      mimeType: mime.getType(
        "./project/1672791927524-corass-project-360_email_for_participant_and_eval.docx"
      ),
      body: fs.createReadStream(
        "./project/1672791927524-corass-project-360_email_for_participant_and_eval.docx"
      ),
    };
    drive.files.create(
      {
        resource: fileMetadata,
        media: media,
        fields: "id",
      },
      async (err, file) => {
        if (err) {
          // Handle the error
          console.error(err);
          return;
        }
        mainId = file.data.id;
        console.log(`File ID: ${file.data.id}`);
        const permission = {
          type: "anyone",
          role: "writer",
          allowFileDiscovery: true,
        };
        drive.permissions.create(
          {
            fileId: mainId,
            sendNotificationEmail: false,
            resource: permission,
          },
          (err, res) => {
            if (err) {
              // Handle the error
              console.error(err);
              return;
            }
            done();
          }
        );
      }
    );

    function done() {
      res.render("template.ejs", { id: mainId });
    }
  } catch (error) {
    console.log(error);
  }
};
exports.viewDocument = async (req, res) => {
  try {
    const { docId } = req.params;
    const doc = await ProjectSubmission.findOne({
      where: {
        id: docId,
      },
      raw: true,
    });
    res.render("studentTemplate.ejs", { doc });
  } catch (error) {
    return res.send("Error Fetching your document, Please contact the admin");
  }
};

exports.bindingReceipt = async (req, res) => {
  const userId = req.params.userId;

  const user = await User.findOne({
    where: {
      id: userId,
    },
  });
  const profile = await Profile.findOne({
    where: { user_id: userId },
    include: [
      {
        model: User,
        attributes: ["username"],
      },
      {
        model: Study_modes,
        attributes: ["name"],
      },
      {
        model: Department,
        attributes: ["id", "name"],
        include: [
          {
            model: Institute,
            attributes: ["name"],
          },
        ],
      },
    ],
  });
  const MypaymentHistory = await Bindingpayment.findOne({
    where: {
      user_id: userId,
      txn_status: "success",
    },
  });

  const url = req.headers.host + req.url;
  qr.toDataURL(url, (err, src) => {
    if (err) res.send("Error occured");

    return res.render("student/binding-receipt.ejs", {
      user,
      MypaymentHistory,
      subscriptions: req.subscriptions,
      profile,
      src,
    });
  });
};
exports.allReceipt = async (req, res) => {
  try {
    const userId = req.query.username;
    let eachPakages = [];
    const user = await User.findOne({
      where: {
        username: userId,
      },
      raw: true,
    });
    if (!user) return res.redirect("/student-dashboard");
    const profile = await Profile.findOne({
      where: { user_id: user.id },
      include: [
        {
          model: User,
          attributes: ["username"],
        },
        {
          model: Study_modes,
          attributes: ["name"],
        },
        {
          model: Department,
          attributes: ["id", "name"],
          include: [
            {
              model: Institute,
              attributes: ["name"],
            },
          ],
        },
      ],
    });
    const MypaymentHistory = await Bindingpayment.findOne({
      where: {
        user_id: user.id,
        txn_status: "success",
      },
    });
    const GetSession = await SchoolSessions.findAll({});
    const allPayment = await paymentHistory.findAll({
      where: {
        username: user.username,
        txn_status: "success",
      },
      raw: true,
    });
    for (const getPayemtHistories of allPayment) {
      const GetPackages = await Packages.findOne({
        where: {
          id: getPayemtHistories.package_id,
        },
      });
      eachPakages.push({
        ...getPayemtHistories,
        package_name: GetPackages?.name,
      });
    }
    const url = req.headers.host + req.url;
    qr.toDataURL(url, (err, src) => {
      if (err) res.send("Error occured");

      return res.render("combinedReceipt.ejs", {
        user,
        getPayemtHistory: eachPakages,
        subscriptions: req.subscriptions,
        profile,
        src,
        Sessions: GetSession[0].name,
        bindingPayment: MypaymentHistory,
      });
    });
  } catch (error) {
    return res.send("Error Fetching your receipt, Please contact the admin");
    return res.redirect("/student-dashboard");
  }
};
exports.acknownledgeSlip = async (req, res) => {
  try {
    const userId = req.query.username;

    const project = await ProjectTopic.findOne({
      where: { student_user_id: userId, active: true, is_approved: true },
      include: [
        {
          model: ProjectSubmission,
          require: true,
          where: { document_category_id: 7 },
          include: [
            {
              model: DocumentCategory,
              attributes: ["name"],
            },
            {
              model: ProjectTopic,
              include: [
                {
                  model: User,
                  as: "student",
                  attributes: ["username", "email"],
                  include: [
                    {
                      model: Profile,
                      attributes: [
                        "firstname",
                        "lastname",
                        "middlename",
                        "photo_path",
                        "receipt_number"
                      ],
                      include: [
                        {
                          model: Study_modes,
                          attributes: ["name"],
                        },
                        {
                          model: Department,
                          attributes: ["id", "name"],
                          include: [
                            {
                              model: Institute,
                              attributes: ["name"],
                            },
                          ],
                        },
                      ],
                    },
                  ],
                },
              ],
            },
          ],
        },
      ],
    });
    const GetSession = await SchoolSessions.findOne({
      where: { status: true },
    });
    const url = req.headers.host + req.url;
    qr.toDataURL(url, (err, src) => {
      if (err) res.send("Error occured");

      return res.render("ack2.ejs", {
        project,
        subscriptions: req.subscriptions,
        src,
        Sessions: GetSession.name,
      });
    });
  } catch (error) {
    res.send("An error occured, Please try again later!");
  }
};
