const db = require("../models");
const API = require('../helper/API_Response');
const db_helper = require("../helper/db_helper");
const helper = require("../helper/helper");
const { User, Version, Navigation, Onbording, Cohort,
  SelfPacedSubscription, KnowledgeAsses, MindMap,
  Video, Practicetest, SelfPacedOneTime, ShortUrl } = require("../models");

exports.getUserById = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const all = await User.findAll({
    where: {
      status: 0,
      id: input.id
    }
  })
  res.status(200).send(API._200(all));
};
exports.getUserByEmail = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const all = await User.findAll({
    where: {
      status: 0,
      email: input.email
    }
  })
  res.status(200).send(API._200(await all));
};
exports.by_certy = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  // const input = req.body
  const all = await Version.findAll({
    where: {
      certy_id: input.certy_id
    }
  })
  res.status(200).send(API._200(all));
};
exports.addreview = async (req, res) => {
  // const input = req.body
  const input = await helper.decryptRequest(req.body.data);
  const data = await db_helper.selectByWhere("FlashcardReviews", { 'user_id': input.user_id, 'device_type': input.device_type, 'app_type': input.app_type })
  if (data.length > 0) {
    input["id"] = data[0].id;
    res.status(200).send(API._200(await db_helper.update("FlashcardReviews", input)));
  } else {
    res.status(200).send(API._200(await db_helper.addData("FlashcardReviews", input)));
  }
};
exports.getreview = async (req, res) => {
  // const input = req.body
  const input = await helper.decryptRequest(req.body.data);
  const data = await db_helper.selectByWhere("FlashcardReviews", { 'user_id': input.user_id, 'device_type': input.device_type, 'app_type': input.app_type })
  res.status(200).send(API._200(await data));
};
exports.getsetting = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const setting = await Navigation.findAll({
    where: {
      user_id: input.user_id,
      status: 0
    }
  })
  if (setting.length <= 0) {
    await db_helper.addData("Navigation", input);
    const sett = await Navigation.findAll({
      where: {
        user_id: input.user_id,
        status: 0
      }
    });
    res.status(200).send(API._200(await sett));
  } else {
    res.status(200).send(API._200(await setting));
  }
};
exports.setsetting = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const data = await db_helper.selectByWhere("Navigation", { 'user_id': input.user_id })
  if (data.length <= 0) {
    res.status(200).send(API._200(await db_helper.addData("Navigation", input)));

  } else {
    let sql = "update app_nav_settings set card_know= :card_know, need_review= :need_review, card_not_seen= :card_not_seen, terms_def= :terms_def, shuffle= :shuffle where user_id= :user_id";
    let que = await db.sequelize.query(sql, { replacements: { card_know: input.card_know, need_review: input.need_review, card_not_seen: input.card_not_seen, terms_def: input.terms_def, shuffle: input.shuffle, user_id: input.user_id } });
    const sett = await Navigation.findAll({
      where: {
        user_id: input.user_id,
        status: 0
      }
    });
    res.status(200).send(API._200(await sett));

  }
};
exports.addsupport = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.addData("AppSupport", input)));

};
exports.update_student_welcome_flow = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  if (input.email) {
    const user = await User.findOne({
      where: { email: input.email }
    });
    if (input.welcome_flow) user.welcome_flow = input.welcome_flow;
    if (input.welcome_flow == 0) {
      user.welcome_flow = 0;
      user.onbording_date = new Date().toISOString()
    }
    if (input.cohort_id != "") {
      let myuId = await user.id;
      const onbording = await Onbording.findOne({
        where: {
          user_id: myuId,
          cohort_id: input.cohort_id,
          status: 0
        }
      });
      if (onbording) {
        if (input.welcome_flow) onbording.welcome_flow = input.welcome_flow;
        if (input.welcome_flow == 0) {
          onbording.welcome_flow = 0;
          onbording.onbording_date = new Date().toISOString()
        }
        await onbording.save()
      }
    }
    let result = await user.save();
    res.status(200).send(API._200(await result));

  } else {
    const user = await User.findOne({
      where: { id: input.id }
    });
    if (input.welcome_flow) user.welcome_flow = input.welcome_flow;
    if (input.welcome_flow == 0) {
      user.welcome_flow = 0;
      user.onbording_date = new Date().toISOString()
    }
    if (input.cohort_id != "") {
      let myuId = await user.id;
      const onbording = await Onbording.findOne({
        where: {
          user_id: myuId,
          cohort_id: input.cohort_id,
          status: 0
        }
      });
      if (onbording) {
        if (input.welcome_flow) onbording.welcome_flow = input.welcome_flow;
        if (input.welcome_flow == 0) {
          onbording.welcome_flow = 0;
          onbording.onbording_date = new Date().toISOString()

        }
        await onbording.save()
      }
    }
    let result = await user.save();
    res.status(200).send(API._200(await result));

  }
};
exports.getallalias = async (req, res) => {
  let all = await db_helper.query("SELECT aliasname FROM users WHERE status=0 AND aliasname IS NOT NULL");
  res.status(200).send(API._200(await all[0]));
};
exports.updateuserbyemail = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const user = await User.findOne({
    where: { email: input.email }
  });
  if (!user) {
    res.status(404).send(API._404({ message: `User with email: ${input.email} was not found` }));
  }
  if (input.name) user.name = input.name;
  if (input.email) user.email = input.email;
  if (input.roll_id) user.roll_id = input.roll_id;
  if (input.permissions) user.permissions = input.permissions;
  if (input.email_verified_at) user.email_verified_at = input.email_verified_at;
  if (input.email_verified) user.email_verified = input.email_verified;
  if (input.free_flashcard) user.free_flashcard = input.free_flashcard;
  if (input.free_practque) user.free_practque = input.free_practque;
  if (input.free_flashccsp) user.free_flashccsp = input.free_flashccsp;
  if (input.pass_rest_code) user.pass_rest_code = input.pass_rest_code;
  if (input.calling_code) user.calling_code = input.calling_code;
  if (input.avatar_url) user.avatar_url = input.avatar_url;
  if (input.is_first) user.is_first = input.is_first;
  if (input.aliasname) user.aliasname = input.aliasname;
  if (input.is_temp) user.is_temp = input.is_temp;
  if (input.authy_id) user.authy_id = input.authy_id;
  if (input.is_live) user.is_live = input.is_live;
  if (input.stripe_customer_id) user.stripe_customer_id = input.stripe_customer_id;
  if (input.course_id) user.course_id = input.course_id;
  if (input.user_time_zone) user.user_time_zone = input.user_time_zone;
  if (input.allow_access) user.allow_access = input.allow_access;
  if (input.onboard_cohort) user.onboard_cohort = input.onboard_cohort;
  if (input.is_selfpaced) user.is_selfpaced = input.is_selfpaced;
  if (input.welcome_flow) user.welcome_flow = input.welcome_flow;
  if (input.expire_password) user.expire_password = input.expire_password;

  user.remember_token = helper.generateAuthToken();
  if (input.password) user.password = helper.getHashedPassword(input.password);
  res.status(200).send(API._200(await user.save()));

};
exports.shortvideo = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  var data = {
    qr_code: input.qr_code,
    status: 0
  }
  if (input.type == 'video')
    res.status(200).send(API._200(await db_helper.selectByWhere("Video", data)));
  else if (input.type == 'mind') {
    if (data.qr_code.startsWith("/")) {
      data.qr_code = data.qr_code.replace("/", "")
    }
    res.status(200).send(API._200(await db_helper.selectByWhere("MindMap", data)));
  }
  else {
    var shorturldata = {
      shorturl: input.qr_code,
      status: 0
    }
    res.status(200).send(API._200(await db_helper.selectByWhere("ShortUrl", shorturldata)));
  }

};
exports.update_onbording = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const onbording = await Onbording.findOne({
    where: {
      user_id: input.user_id,
      cohort_id: input.cohort_id,
      status: 0
    }
  });
  if (!onbording) {
    res.status(404).send(API._404({ message: `Onbording with user_id: ${input.user_id} was not found` }));
  }
  if (input.user_id) onbording.user_id = input.user_id;
  if (input.cohort_id) onbording.cohort_id = input.cohort_id;
  if (input.is_expire) onbording.is_expire = input.is_expire;
  if (input.link_expire_on) onbording.link_expire_on = input.link_expire_on;
  if (input.completed_on) onbording.completed_on = input.completed_on;
  if (input.welcome_flow) onbording.welcome_flow = input.welcome_flow;
  if (input.is_selfpaced) onbording.is_selfpaced = input.is_selfpaced;
  if (input.opt_in) onbording.opt_in = input.opt_in;
  res.status(200).send(API._200(await onbording.save()));


};
exports.add_onbording = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  if (input.cohort_id != 0 && input.user_id != 0) {
    let usr = {
      "user_id": input.user_id,
      "cohort_id": input.cohort_id,
    }
    const cc = await db_helper.selectByWhere("Onbording", usr);
    if (cc.length > 0) {
      res.status(200).send(API._200(await cc[0]));

    } else {
      let req = {
        "user_id": input.user_id,
        "is_main": 1,
        "is_expire": 1
      }
      const main = await db_helper.selectByWhere("Onbording", req);
      if (main.length > 0) {
        input["is_main"] = 0;
      } else {
        input["is_main"] = 1;
      }
      res.status(200).send(API._200(await db_helper.addData("Onbording", input)));
    }
  }
  else {
    res.status(400).send(API._400({ message: "All params required" }));
  }
};
exports.add_activity_tracker = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.addData("ActivityTracker", input)));
};
exports.add_authy = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  input["qr_code"] = req.body.qr_code;
  res.status(200).send(API._200(await db_helper.addData("AuthyMaster", input)));
};
exports.update_two_fact_tab = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.update("User", input)));
};
exports.get_welcome_links = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  if (input.cohort_id == null || input.cohort_id == undefined) {
    const cohorts = await db.sequelize.query("select id from cohorts where find_in_set((select id from users where email='" + input.email + "'),userslist) limit 1")
      .then(function (data) {
        return Array.from(new Set(data[0]));
      })
    input.cohort_id = cohorts[0].id;
  }
  const result = await db.sequelize.query("select c.id cohort_id,c.cohort_name,course_type,c.certi_id,cert.hybrid_welcome_video,cert.hybrid_welcome_thumbnail,cert.hybrid_course_thumbnail,cert.self_welcome_video,cert.self_welcome_thumbnail,cert.self_course_thumbnail,cert.live_welcome_video,cert.live_welcome_thumbnail,cert.live_course_thumbnail from cohorts as c left join certificates as cert on cert.id=c.certi_id where c.id= :cohort_id", { replacements: { cohort_id: input.cohort_id } }).then((res) => {
    return Array.from(new Set(res));
  })
  res.status(200).send(API._200(await result));

};
exports.get_expirydate_onboarding = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const time = await db.sequelize.query("select DATE_ADD(createdAt, INTERVAL access_duration DAY) expiry_date,createdAt from payment_transactions where user_id=:user_id and payment_type in(select course_type from cohorts where id= :cohort_id) and cohort_id= :cohort_id and plan_id in(select method_id from cohorts where id= :cohort_id) order by id desc limit 1", { replacements: { user_id: input.user_id, cohort_id: input.cohort_id } })
    .then(function (data) {
      return Array.from(new Set(data[0]));
    })
  res.status(200).send(API._200(await time));

};
exports.add_failed_emails = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.addData("FailedEmail", input)));
};
exports.add_payment_transaction = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.addData("PaymentTransaction", input)));
};
exports.add_selfcohort_student = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);

  const cohort = await Cohort.findByPk(input.cohortIds);
  let uid = cohort.userslist;
  let newUsers = "";
  if (uid.length > 0) {
    newUsers = uid + "," + input.user_id;
  }
  else {
    newUsers = input.user_id;
  }
  if (newUsers.endsWith(",")) {
    newUsers = newUsers.substring(0, newUsers.length - 1);
  }
  if (newUsers.startsWith(",")) {
    newUsers = newUsers.substring(1, newUsers.length);
  }
  cohort.userslist = newUsers;
  res.status(200).send(API._200(await cohort.save()));

};
exports.fetch_user_payment = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const time = await db.sequelize.query("select * from payment_transactions where user_id in(select id from users where email='" + input.email + "') order by id desc limit 1")
    .then(function (data) {
      return Array.from(new Set(data[0]));
    })
  let response = {
    link: "",
    pay: false
  }
  if (time.length > 0) {
    const monthNames = ["January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December"
    ];

    let links = {
      "user_id": time[0].user_id,
      "cohort": time[0].cohort_id,
      "date": monthNames[new Date(time[0].createdAt).getMonth()] + " " + await getOrdinal(new Date(time[0].createdAt).getDate())
    }
    let my_link = "http://64.23.254.43/welcomertemp/" + Buffer.from(JSON.stringify(links)).toString('base64');
    response.link = my_link;
    response.pay = true;
  }
  res.status(200).send(API._200(await response));
};
exports.get_membership = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const sub = await SelfPacedSubscription.findAll({
    where: {
      status: 0,
      id: input.sub_id
    }
  });
  const mat = await db.sequelize.query("select * from self_paced_materials where status=0 and method_id= :sub_id and method_type='subscription' and is_checked=1", { replacements: { sub_id: input.sub_id } })
    .then(function (data) {
      return Array.from(new Set(data[0]));
    })
  for (let i = 0; i < mat.length; i++) {
    if (mat[i].material_type == 'KA') {
      const ka = await KnowledgeAsses.findAll({
        where: {
          status: 0,
          id: mat[i].material_id
        },
        attributes: ['knowass_name']
      });
      mat[i]['material_name'] = await ka[0].knowass_name + " - Knowledge Assessment";
    }
    else if (mat[i].material_type == 'Mindmap') {
      const mind = await MindMap.findAll({
        where: {
          status: 0,
          id: mat[i].material_id
        },
        attributes: ['name']
      });
      mat[i]['material_name'] = await mind[0].name + " - Mindmap";
    }
    else if (mat[i].material_type == 'Video') {
      const video = await Video.findAll({
        where: {
          status: 0,
          id: mat[i].material_id
        },
        attributes: ['video_title']
      });
      mat[i]['material_name'] = await video[0].video_title + " - Video Lesson";
    }
    else if (mat[i].material_type == 'Test') {
      const pt = await Practicetest.findAll({
        where: {
          status: 0,
          id: mat[i].material_id
        },
        attributes: ['practice_name']
      });
      mat[i]['material_name'] = await pt[0].practice_name + " - Practice Test";
    }

  }

  let response = { "Materials": mat, "Subscription": sub };
  res.status(200).send(API._200(await response));
};

exports.get_onbording = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  let result = await db.sequelize.query("SELECT * FROM onbordings where user_id=:user_id and cohort_id=:cohort_id", { replacements: { cohort_id: input.cohort_id, user_id: input.user_id } }).then((res) => {
    return Array.from(new Set(res));
  })
  res.status(200).send(API._200(await result));
};
exports.get_onetime_membership = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const sub = await SelfPacedOneTime.findAll({
    where: {
      status: 0,
      id: input.sub_id
    }
  });
  const mat = await db.sequelize.query("select * from self_paced_materials where status=0 and method_id= :sub_id and method_type='onetime' and is_checked=1", { replacements: { sub_id: input.sub_id } })
    .then(function (data) {
      return Array.from(new Set(data[0]));
    })
  for (let i = 0; i < mat.length; i++) {
    if (mat[i].material_type == 'KA') {
      const ka = await KnowledgeAsses.findAll({
        where: {
          status: 0,
          id: mat[i].material_id
        },
        attributes: ['knowass_name']
      });
      mat[i]['material_name'] = await ka[0].knowass_name + " - Knowledge Assessment";
    }
    else if (mat[i].material_type == 'Mindmap') {
      const mind = await MindMap.findAll({
        where: {
          status: 0,
          id: mat[i].material_id
        },
        attributes: ['name']
      });
      mat[i]['material_name'] = await mind[0].name + " - Mindmap";
    }
    else if (mat[i].material_type == 'Video') {
      const video = await Video.findAll({
        where: {
          status: 0,
          id: mat[i].material_id
        },
        attributes: ['video_title']
      });
      mat[i]['material_name'] = await video[0].video_title + " - Video Lesson";
    }
    else if (mat[i].material_type == 'Test') {
      const pt = await Practicetest.findAll({
        where: {
          status: 0,
          id: mat[i].material_id
        },
        attributes: ['practice_name']
      });
      mat[i]['material_name'] = await pt[0].practice_name + " - Practice Test";
    }

  }

  let response = { "Materials": mat, "OneTime": sub };
  res.status(200).send(API._200(await response));
};
exports.overdue_notification_stop = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const data = await db_helper.selectByWhere("NotificationSetting", { 'user_id': input.user_id })
  input["oberdue"] = input.overdue_notification;
  if (data.length > 0) {
    input["id"] = data[0].id;
    await db_helper.update("NotificationSetting", input);
  } else {
    await db_helper.addData("NotificationSetting", input);
  }

  res.status(200).send(API._200(await db_helper.query("update users set overdue_notification=" + input.overdue_notification + " where id =" + input.user_id)));
};
exports.save_access_duration = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  let usr = {
    "user_id": input.user_id,
    "cohort_id": input.cohort_id,
  }
  const cc = await db_helper.selectByWhere("AccessDuration", usr);
  if (cc.length > 0) {
    input['id'] = cc[0].id;
    res.status(200).send(API._200(await db_helper.update("AccessDuration", input)));
  } else {
    res.status(200).send(API._200(await db_helper.addData("AccessDuration", input)));
  }
};
exports.save_self_schedule = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  let usr = {
    "user_id": input.user_id,
    "certi_id": input.certi_id
  }
  const cc = await db_helper.selectByWhere("SelfPacedSchedule", usr);
  if (cc.length > 0) {
    res.status(200).send(API._200(await db_helper.update("SelfPacedSchedule", input)));
  } else {
    res.status(200).send(API._200(await db_helper.addData("SelfPacedSchedule", input)));
  }
};
exports.shortvideo = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  var data = {
    qr_code: input.qr_code,
    status: 0
  }
  if (input.type == 'video')
    return API._200(await db_helper.selectByWhere("Video", data));
  else if (input.type == 'mind') {
    if (data.qr_code.startsWith("/")) {
      data.qr_code = data.qr_code.replace("/", "")
    }
    res.status(200).send(API._200(await db_helper.selectByWhere("MindMap", data)));
  }
  else {
    var shorturldata = {
      shorturl: input.qr_code,
      status: 0
    }
    res.status(200).send(API._200(await db_helper.selectByWhere("ShortUrl", shorturldata)));
  }
};
exports.sendOtp = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  let number = Math.floor(100000 + Math.random() * 900000);
  const user = await User.findOne({
    where: { email: input.email }
  });
  user.email_otp = number;
  let html = `<h1>Activation Code</h1><p>Here is your activation code to be entered at E-Learn:</p><h2>${number}</h2>`;
  let data = {
    to: input.email,
    subject: "Email Activation",
    text: html
  }
  helper.sendMail(data)
  user.save()
  res.status(200).send(API._200({}));

};
exports.addshorturl = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.addData('ShortUrl', input)));
};
exports.delete_meeting = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  let data = await db_helper.query("update live_events set is_live=0 where meeting_id='" + input.MeetingId + "'");
  res.status(200).send(API._200(await data));
};
exports.getallShortUrl = async (req, res) => {
  const all = await ShortUrl.findAll({
    where: {
      status: 0
    }
  })
  res.status(200).send(API._200(await all));
};
exports.ShortUrldelete = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.statusChange('ShortUrl', input.id)));
};
exports.ShortUrlupdate = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.update('ShortUrl', input)));
};
exports.update_payment_transaction = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.update("PaymentTransaction", input)));
};
