const db = require("../models");
const API = require('../helper/API_Response');
const db_helper = require("../helper/db_helper");
const helper = require("../helper/helper");
const { User, SelfPacedMaterial, SelfPacedHour, KnowledgeAsses, Practicetest, LiveEvents, Cohort, PaymentTransaction, Certificate, SelfPacedSubscription, SelfPacedOneTime, Video, MindMap, Ketexamtest, SelfPaced } = require("../models");

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,
    "cohort_id": input.cohort_id
  }
  const cc = await db_helper.selectByWhere("SelfPacedSchedule", usr);
  if (cc.length > 0) {
    input["id"] = cc[0].id;
    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.update_user_resource = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const cc = await db.sequelize.query("update users set show_resources=1 where id= :user_id", { replacements: { user_id: input.user_id } }).then((response) => {
    return Array.from(new Set(response));
  })
  res.status(200).send(API._200(await cc));
};
exports.get_expirydate = 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='" + input.course_type + "' and cohort_id= :cohort_id and plan_id= :method_id order by id desc limit 1", { replacements: { cohort_id: input.cohort_id, user_id: input.user_id, method_id: input.method_id } })
    .then(function (data) {
      return Array.from(new Set(data[0]));
    })
  res.status(200).send(API._200(await time));
};
exports.get_membership_materials = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const cc = await db.sequelize.query("select * from self_paced_materials where status=0 and method_id= :method_id and method_type='" + input.method_type + "' and material_type='" + input.material_type + "'", { replacements: { method_id: input.method_id } }).then((res) => {
    return Array.from(new Set(res));
  })
  res.status(200).send(API._200(await cc[0]));
};
exports.get_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,
    "cohort_id": input.cohort_id
  }
  const cc = await db_helper.selectByWhere("SelfPacedSchedule", usr);
  res.status(200).send(API._200(await cc));
};
exports.SaveSelfpaced_User_Schedule = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  let all;
  if (input.length > 0) {
    await db.sequelize.query("delete from selfpaced_class_all_user_schedules where user_id= :user_id and cohort_id=:cohort_id", { replacements: { user_id: input[0].user_id, cohort_id: input[0].cohort_id } })
    all = await db['SelfpacedClassAllUserSchedule'].bulkCreate(input);
  }
  const updateAll = await db_helper.query("update selfpaced_class_all_user_schedules ss inner join cohorts c on c.id=ss.cohort_id JOIN(SELECT @rank := 0) r SET ss.id =@rank:=@rank+1,ss.cohort_name=c.cohort_name; ");

  res.status(200).send(API._200(await all));
};
exports.selfpaced_times = async (req, res) => {
  const all = await db.sequelize.query("SELECT * FROM self_paced_hours")
    .then(function (data) {
      return Array.from(new Set(data[0]));
    })
  res.status(200).send(API._200(await all));
};
exports.update_examdate = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const cc = await db.sequelize.query("UPDATE payment_transactions set exam_date='" + input.exam_date + "' 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 cc[0]));
};
exports.update_section_video_view = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  var already = await db.sequelize.query("SELECT * FROM video_section_views where (type_id= :type_id OR name='" + input.name + "') AND cohort_id= :cohort_id AND user_id= :user_id", { replacements: { type_id: input.type_id, cohort_id: input.cohort_id, user_id: input.user_id } }).then((data) => {
    return Array.from(new Set(data[0]));
  })
  if (already.length <= 0)
    res.status(200).send(API._200(await db_helper.addData('VideoSectionView', input)));
  else {
    input['id'] = already[0].id;
    res.status(200).send(API._200(await db_helper.update('VideoSectionView', input)));
  }
};
exports.add_selfpaced_hours = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const all = await db.sequelize.query("SELECT * FROM self_paced_hours")
    .then(function (data) {
      return Array.from(new Set(data[0]));
    })
  let result = null;
  if (all.length > 0) {
    input['id'] = 1;
    const hour = await SelfPacedHour.findByPk(input.id);
    hour.flashcard_app = input.flashcard_app;
    hour.flashcard_app_revision = input.flashcard_app_revision;
    hour.practice_que_app = input.practice_que_app;
    hour.practice_que_app_revision = input.practice_que_app_revision;
    hour.know_ass_revision = input.know_ass_revision;
    hour.practice_test_revision = input.practice_test_revision;
    result = await hour.save();
  } else {
    result = db_helper.addData("SelfPacedHour", input)
  }
  res.status(200).send(API._200(await result));

};
exports.all = async (req, res) => {
  const all = await db.sequelize.query("select main.*, c.certificate_name, coh.company_id, coh.userslist,coh.knowassessments,coh.practicetests, LENGTH(coh.userslist) - LENGTH(REPLACE(coh.userslist, ',', '')) count_userslist from(select id, certi_id, class_name, description, features_visible, live_events, only_show_study, publish_free_trial, 0 cat_exam_attempts, '' cat_attempts_fee, '' one_time_description, 0 one_time_access_duration, '' one_time_price, cohort_id, pt_id, ka_id, '' array_subscriptions, 'free' course_type, mentor_id, time_zone from  self_paceds where status = 0 union all select id, certi_id, price_label, '' description, features_visible, live_events, only_show_study, publish_subscription, cat_exam_attempts, attempts_fee, '' one_time_description, 0 one_time_access_duration, '' one_time_price, cohort_id, 0 pt_id, 0 ka_id, subscriptions, 'subscription' course_type, mentor_id, time_zone from  self_paced_subscriptions where status = 0 union all select id, certi_id, price_label, '' description, features_visible, live_events, only_show_study, publish_subscription, cat_exam_attempts, attempts_fee, description one_time_description, access_duration, price, cohort_id, 0 pt_id, 0 ka_id, '' array_subscriptions, 'onetime' course_type, mentor_id, time_zone  from self_paced_one_times  where status = 0 )main left join certificates as c on c.id=main.certi_id left join cohorts as coh on coh.id=main.cohort_id  order by c.id")
    .then(function (data) {
      return Array.from(new Set(data[0]));
    })
  for (let i = 0; i < all.length; i++) {
    let users = all[i].userslist;
    if (users) {
      let user_list = await db_helper.query("SELECT id FROM users WHERE id IN(" + users + ")");
      all[i].count_userslist = user_list[0]
    }
  }
  res.status(200).send(API._200(await all));

};
exports.alldropdown = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const ka = await KnowledgeAsses.findAll({
    attributes: ['id', 'knowass_name', 'certi_id'],
    where: {
      status: 0,
      certi_id: input.certi_id
    }
  });
  const pt = await Practicetest.findAll({
    attributes: ['id', 'practice_name', 'certi_id'],
    where: {
      status: 0,
      certi_id: input.certi_id
    }
  });
  const lv = await LiveEvents.findAll({
    attributes: ['id', 'event_name', 'start_date', 'start_time', 'time_zone'],
    where: {
      status: 0,
      certi_id: input.certi_id
    }
  });
  let response = { "KnowledgeAssessments": ka, "PracticeExams": pt, "LiveEvents": lv };
  res.status(200).send(API._200(await response));

};
exports.delete = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  await db_helper.query("delete from self_paced_one_times where certi_id=" + input.id);
  await db_helper.query("delete from self_paced_subscriptions where certi_id=" + input.id);
  await db_helper.query("update cohorts set status=1 where certi_id=" + input.id);
  res.status(200).send(API._200(await db_helper.query("delete from self_paceds where certi_id=" + input.id)));
};
exports.delete_self_class = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  var result = []
  if (input.course_type == 'subscription') {
    result = await db.sequelize.query("delete from self_paced_subscriptions where id= :id", { replacements: { id: input.id } }).then((res) => {
      return Array.from(new Set(res));
    })
  }
  if (input.course_type == 'onetime') {
    result = await db.sequelize.query("delete from self_paced_one_times where id= :id", { replacements: { id: input.id } }).then((res) => {
      return Array.from(new Set(res));
    })
  }
  if (input.cohort_id) {
    await db.sequelize.query("delete from payment_transactions where payment_type='" + input.course_type + "' and plan_id= :id and cohort_id= :cohort_id", { replacements: { id: input.id, cohort_id: input.cohort_id } })
    await db.sequelize.query("delete from cohorts where id= :cohort_id", { replacements: { cohort_id: input.cohort_id } })
  }
  res.status(200).send(API._200(await result));
};
exports.enrollments_detail = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const all = await PaymentTransaction.findAll({
    where: {
      status: 0,
      user_id: input.user_id
    },
    include: [{
      model: Certificate,
      attributes: ['id', 'certificate_name']
    }]
  })

  for (let i = 0; i < all.length; i++) {
    const cohort = await Cohort.findAll({
      where: {
        status: 0,
        id: all[i].cohort_id
      },
      attributes: ['cohort_name', 'flashcard_access', 'question_access']
    })
    if (all[i].plan_id == 0) {
      if (cohort.length > 0)
        all[i].email = { price_label: cohort[0].cohort_name, flashcard_access: cohort[0].flashcard_access, question_access: cohort[0].question_access };
    } else {
      if (all[i].payment_type == "subscription") {
        const sub = await SelfPacedSubscription.findAll({
          where: {
            status: 0,
            id: all[i].plan_id
          },
          attributes: ['id', 'price_label']
        })
        let access = { id: sub[0].id, price_label: sub[0].price_label, flashcard_access: cohort[0].flashcard_access, question_access: cohort[0].question_access };
        all[i].email = access;

      } else if (all[i].payment_type == "onetime") {
        const one = await SelfPacedOneTime.findAll({
          where: {
            status: 0,
            id: all[i].plan_id,
          },
          attributes: ['id', 'price_label']
        })
        let access = { id: one[0].id, price_label: one[0].price_label, flashcard_access: cohort[0].flashcard_access, question_access: cohort[0].question_access };
        all[i].email = access
      }
    }
  }
  res.status(200).send(API._200(await all));
};
exports.get_all_hybrid_materials = async (req, res) => {
  const ka = await KnowledgeAsses.findAll({
    attributes: ['id', 'knowass_name', 'certi_id'],
    where: {
      status: 0,
    }
  });
  const pt = await Practicetest.findAll({
    attributes: ['id', 'practice_name', 'certi_id'],
    where: {
      status: 0,
    }
  });
  const vd = await Video.findAll({
    attributes: ['id', 'video_title', 'certi_id'],
    where: {
      status: 0,
    }
  });
  const md = await MindMap.findAll({
    attributes: ['id', 'name', 'certi_id'],
    where: {
      status: 0,
    }
  });
  const catexam = await Ketexamtest.findAll({
    attributes: ['id', 'ketexam_name', 'certi_id'],
    where: {
      status: 0,
    }
  });
  let response = { "KnowledgeAssessments": ka, "PracticeExams": pt, "Videos": vd, "MindMaps": md, "CatExams": catexam };
  res.status(200).send(API._200(await response));
};
exports.get_all_materials = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const ka = await KnowledgeAsses.findAll({
    attributes: ['id', 'knowass_name'],
    where: {
      status: 0,
      certi_id: input.certi_id
    }
  });
  const pt = await Practicetest.findAll({
    attributes: ['id', 'practice_name', 'certi_id'],
    where: {
      status: 0,
      certi_id: input.certi_id
    }
  });
  const vd = await Video.findAll({
    attributes: ['id', 'video_title'],
    where: {
      status: 0,
      certi_id: input.certi_id
    }
  });
  const md = await MindMap.findAll({
    attributes: ['id', 'name'],
    where: {
      status: 0,
      certi_id: input.certi_id
    }
  });
  let response = { "KnowledgeAssessments": ka, "PracticeExams": pt, "Videos": vd, "MindMaps": md };
  res.status(200).send(API._200(await response));
};
exports.get_all_mentor = async (req, res) => {
  const all = await User.findAll({
    where: {
      status: 0,
      roll_id: 1
    },
    attributes: ['id', 'name', 'email']
  })
  res.status(200).send(API._200(await all));
};
exports.get_saved_materials = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const sub = await SelfPacedMaterial.findAll({
    where: {
      status: 0,
      method_id: input.method_id,
      method_type: input.method_type
    }
  });
  res.status(200).send(API._200(await sub));
};
exports.get_selfpaced_summary_report = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  var output = [];
  if (input.userslist) {
    var users = await db.sequelize.query("SELECT id,mentor_notes,mentor_id,aliasname,name,email,onbording_date,schedule_date exam_date FROM users WHERE id IN(" + input.userslist + ")")
      .then(function (data) {
        return Array.from(new Set(data[0]));
      })
    for (let u = 0; u < users.length; u++) {
      let log = await db_helper.query("select createdAt FROM login_logs WHERE user_id= " + users[u].id + " order by createdAt DESC limit 1; SELECT count(*) total_KA_complete FROM knowcompletes WHERE user_id=" + users[u].id + " AND cohort_id=" + input.id + "; select * from flashans_offlines where UserId=" + users[u].id + " and cohort_id=" + input.id + " limit 1")
      let know = await db_helper.query("select sum(case when kaqa.correct=1 then 1 else 0 end) ttlpointget,(select count(*) from know_ass_ques where status=0 and ass_id=ka.id) as ttlpoint from know_ass_ques_ans as kaqa left join knowledge_asses as ka on ka.id=kaqa.ass_id where kaqa.active=1 and kaqa.cohort_id= " + input.id + " and kaqa.user_id= " + users[u].id + " group by ka.id")
      let practice = await db_helper.query("select sum(case when ptqa.correct=1 then 1 else 0 end) ttlpointget,(select count(*) from practiceques where status=0 and test_id=pt.id) as ttlpoint from practice_ans as ptqa left join practicetests as pt on pt.id=ptqa.test_id where ptqa.active=1 and ptqa.cohort_id=" + input.id + " and ptqa.user_id=" + users[u].id + "  group by pt.id; SELECT count(*) total_PT_complete FROM ptestcomplates WHERE user_id=" + users[u].id + " AND cohort_id=" + input.id)
      let flash;
      if (log[0][2].length > 0) {
        flash = await db_helper.query("select count(distinct (case when user_res = 1 then cid end)) as ttlright,count(distinct (case when user_res = 2 then cid end)) as ttlreview,count(distinct (case when mark = 1 then cid end)) as ttlbookmark, count(distinct (case when(notes = 1 && user_res=0)  then cid end)) as ttlnotes, ifnull(ttlcards,0)ttlcards from flashans_offlines fo right join (SELECT COUNT(*) as ttlcards FROM flashcards WHERE certi_id in(select certi_id from cohorts where id=" + input.id + ") and status=0)fl on 1=1 where UserId=" + users[u].id + " and cohort_id=" + input.id);
      }
      else {
        flash = await db_helper.query("select count(distinct (case when user_res = 1 then cid end)) as ttlright,count(distinct (case when user_res = 2 then cid end)) as ttlreview,count(distinct (case when mark = 1 then cid end)) as ttlbookmark, count(distinct (case when(notes = 1 && user_res=0)  then cid end)) as ttlnotes, ifnull(ttlcards,0)ttlcards from flashans_offlines fo right join (SELECT COUNT(*) as ttlcards FROM flashcards WHERE certi_id in(select certi_id from cohorts where id=" + input.id + ") and status=0)fl on 1=1 where UserId=" + users[u].id);
      }
      output.push({
        cohort_id: input.id,
        userslist: input.userslist,
        knowassessments: input.knowassessments,
        practicetests: input.practicetests,
        user_id: users[u].id,
        mentor_notes: users[u].mentor_notes,
        mentor_id: users[u].mentor_id,
        aliasname: users[u].aliasname,
        name: users[u].name,
        email: users[u].email,
        onbording_date: users[u].onbording_date,
        exam_date: users[u].exam_date,
        last_activity: log[0][0].length > 0 ? log[0][0][0].createdAt : null,
        total_KA_complete: log[0][1].length > 0 ? log[0][1][0].total_KA_complete : 0,
        total_PT_complete: practice[0][1].length > 0 ? practice[0][1][0].total_PT_complete : 0,
        knowledge: know[0],
        practice: practice[0][0],
        flashcards: flash[0]
      })
    }

  }
  res.status(200).send(API._200(await output));
};
exports.pay_trn_byid = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const time = await db.sequelize.query("select *,DATE_FORMAT(createdAt,'%b %d,%Y') createdAt,DATE_FORMAT(DATE_ADD(createdAt, INTERVAL access_duration DAY),'%b %d,%Y') expiry_date,DATE_FORMAT(DATE_ADD(createdAt, INTERVAL access_duration+1 DAY),'%b %d,%Y') next_date from payment_transactions where id= :id", { replacements: { id: input.id } })
    .then(function (data) {
      return Array.from(new Set(data[0]));
    })
  res.status(200).send(API._200(await time));
};
exports.remove_enrollments = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  await db.sequelize.query("delete from payment_transactions where id= :id", { replacements: { id: input.id } })
  await db.sequelize.query("update users set course_id=null where id= :user_id", { replacements: { user_id: input.user_id } })
  const cohort = await Cohort.findByPk(input.cohort_id);
  let users = "";
  users = cohort.userslist;
  let ids = "";
  for (let i = 0; i < users.length; i++) {
    if (users[i] != input.user_id) {
      ids += users[i] + ","
    }
  }
  if (ids.endsWith(",")) {
    ids = ids.substring(0, ids.length - 1);
  }
  if (ids.startsWith(",")) {
    ids = ids.substring(1, ids.length);
  }
  cohort.userslist = ids;
  let result = cohort.save();
  res.status(200).send(API._200(await result));
};
exports.save_materials = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  await db.sequelize.query("delete from self_paced_materials where method_id= :method_id and method_type='" + input.method_type + "'", { replacements: { method_id: input.method_id } })

  let Subscriptions = input.Subscriptions;
  let OneTime = input.OneTime;
  let data;
  for (let i = 0; i < Subscriptions.length; i++) {
    data = await db_helper.addData("SelfPacedMaterial", Subscriptions[i])
  }
  for (let i = 0; i < OneTime.length; i++) {
    data = await db_helper.addData("SelfPacedMaterial", OneTime[i])
  }
  res.status(200).send(API._200(await data));
};
exports.selfpaced_classes = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  const all = await SelfPaced.findAll({
    where: {
      status: 0,
      certi_id: input.certi_id
    }
  })
  const sub = await SelfPacedSubscription.findAll({
    where: {
      status: 0,
      certi_id: input.certi_id
    }
  })
  const one = await SelfPacedOneTime.findAll({
    where: {
      status: 0,
      certi_id: input.certi_id
    }
  })
  var data = { all, sub, one };
  res.status(200).send(API._200(await data));
};
exports.update = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.update('SelfPaced', input)));
};
exports.update_mentor_notes = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  res.status(200).send(API._200(await db_helper.query("update users set mentor_notes='" + input.notes + "' where id=" + input.user_id)));
};
exports.update_one_time = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  if (input.id == 0)
    res.status(200).send(API._200(await db_helper.addData('SelfPacedOneTime', input)));
  else
    res.status(200).send(API._200(await db_helper.update('SelfPacedOneTime', input)));
};
exports.update_subscription = async (req, res) => {
  const input = await helper.decryptRequest(req.body.data);
  if (input.id == 0)
    res.status(200).send(API._200(await db_helper.addData('SelfPacedSubscription', input)));
  else
    res.status(200).send(API._200(await db_helper.update('SelfPacedSubscription', input)));
};