"use strict";
appCore.controller("MyDiaryUnfilledReportWeeklyCtrl", ["$state", "$scope", "$http", "$timeout", "vServices", "$uibModal", "$document",
  function ($state, $scope, $http, $timeout, vServices, $uibModal, $document) {
    $scope.$root.page.title = "My Diary Unfilled Report";
    $scope.project = [];
    $scope.selectAll = {selected: false};
    $scope.CheckedId = "";
    $scope.tblheader = [];
    $scope.revenueCenters = [];
    $scope.showLockDiv = false;
    $scope.myDiary = {default: [], project: [], heroes: [], datatable: []};
    $scope.prebilled = [];
    $scope.consolidatedData = [];
    $scope.reportViewModel = '2';
    $scope.billingType = '';
    $scope.invoiceData = {};
    $scope.dTable=null;
    $scope.showBtn= true;
    $scope.numOfWeeks = 0;
    
    $scope.weekHorusAA = () =>{
          // calculate weekly sum of hours excluding Saturday and Sunday
          let weeklySum = 0;
          let daysCounter = 0;

          for (let i = 0; i < hoursPerDay.length; i++) {
            const date = new Date(year, month, i + 1);
            const dayOfWeek = date.getDay();

            if (dayOfWeek !== 0 && dayOfWeek !== 6) { // exclude Saturday and Sunday
            weeklySum += hoursPerDay[i];
            daysCounter++;
            }

            if (dayOfWeek === 0 || i === hoursPerDay.length - 1) { // Sunday or end of month
            // console.log(`Weekly hours (Week ${Math.ceil(daysCounter / 5)}): ${weeklySum}`);
            weeklySum = 0;
            daysCounter = 0;
            }
          }
  }

    $scope.filter = {
      fromDate: moment().subtract(2, "days").format("DD-MM-YYYY"),
      toDate: moment().format("DD-MM-YYYY"),
      rc_name:0,
      minHours: 0,
      project: 0,
      proj_id:0,
      monthyear:'',
      pageName: "My Diary Report"
    };
    let numOr0 = n => isNaN(n) ? 0 : n;
    $scope.sum = (item, list) => list.map(o => o[item]).reduce((a, b) => parseFloat(numOr0(a)) + parseFloat(numOr0(b)));
    $scope.tempArry = [];

    const convertDataForProject = res => {
      if (res) {
        $scope.project = [];
        $scope.project.push({id: 0, name: " Select Project", proj_status: "active"});
        res = $scope.$root.sort(res, "proj_name");
        res = res.filter(proj => proj.proj_status === "active");
        res.map((o) => $scope.project.push({id: o.projectid, name: o.proj_name, proj_status: o.proj_status, proj_mydiaryLockDate: o.proj_mydiaryLockDate}));
        $scope.filter.project = $scope.project[0];
      }
    };
    $scope.clickSelectAll = function () {
      angular.forEach($scope.myDiary.default, function (value) {
        value.selected = $scope.selectAll.selected;
        if ($scope.selectAll.selected) {
          if ($scope.CheckedId.length == 0) {
            $scope.CheckedId = value.mydiaryid;
          }
          else {
            $scope.CheckedId += ", " + value.mydiaryid;
          }
        }
      });
      if (!$scope.selectAll.selected) $scope.CheckedId = "";
    };
    $scope.updateLockedDate = function () {
      if (!$scope.myDiaryLock.LockTillDate) toastr.error("Please provide valid Date to Lock.");
      else vServices.callApi("mydiary/lock", "PUT", {proj_id: $scope.filter.project.id, lock_date: $scope.myDiaryLock.LockTillDate}).then((res) => {
        if (res) {
          //toastr.success(res, "Message");
        }
        $state.go($state.current, {}, {reload: true});
      });
    };
    $scope.Checked = function () {
      $scope.CheckedId = "";
      $scope.selectAll.selected = true;
      angular.forEach($scope.myDiary.default, function (value) {
        if (value.selected) {
          if ($scope.CheckedId.length == 0) {
            $scope.CheckedId = value.mydiaryid;
          }
          else {
            $scope.CheckedId += ", " + value.mydiaryid;
          }
        }
        else $scope.selectAll.selected = false;
      });
    };


    const convertDataForMyDiaryWeekly = res => {
     if($scope.dTable)$scope.dTable.destroy();
      document.getElementById('blackout').style.display = 'block';
      $scope.tblheader=[];
      $scope.myDiary.datatable = [];
      $scope.showLoader = false;
      const yr = moment($scope.filter.monthyear).format('YYYY');
      const mnt =moment($scope.filter.monthyear).format('MM')
      const firstDayOfMonth = new Date(yr, mnt - 1, 1).getDay();
      const secondDayOfMonth = new Date(yr, mnt - 1, 2).getDay();
      res.forEach(i=>{
        let countPrebilled=0;
        let countHours=0;
        let temArrHours = [];
        let temArrPrebilledHours = [];
        let totalBillingDays=0;
        let weeklySumHero = 0;
        let weeklySumMngr = 0;
        let daysCounter = 0;
        let weekCountInMonth = 0;
        let weekendsCount = $scope.getSaturdaysAndSundays(moment($scope.filter.monthyear).format('YYYY'),moment($scope.filter.monthyear).format('MM'));
        i.logged_hours.forEach((j,index)=>{
            totalBillingDays+=1;
            const leaves = j.logtype.split(',');
            j.dayType = leaves;
            const dayOfWeek = moment(j.inserton).day();
            const empOnLeave = leaves.includes('16') || leaves.includes('17') || leaves.includes('22') || leaves.includes('23') ? false : true;
            if(!j.prebilled && (dayOfWeek !== 0 || dayOfWeek !== 6) && empOnLeave){
              let hour = j.hours ? parseFloat(j.hours) : 0;
              countHours=parseFloat(hour);
              countPrebilled=parseFloat(hour);
            }
            if(j.prebilled && (dayOfWeek !== 0 || dayOfWeek !== 6) && empOnLeave){
              let prebilled = j.prebilled ? parseFloat(j.prebilled) : 0;
              let hour = j.hours ? parseFloat(j.hours) : 0;
              countPrebilled=parseFloat(prebilled);
              countHours=parseFloat(hour);
            }
            
            if (dayOfWeek !== 0 && dayOfWeek !== 6 && empOnLeave) { // exclude Saturday and Sunday
              weeklySumHero+= countHours;
              weeklySumMngr+= countPrebilled;
              daysCounter++;
            }
            // console.log( 'dayOfWeek ' +dayOfWeek + ' firstDayOfMonth ' + firstDayOfMonth + ' firstDayOfMonthCond ' + firstDayOfMonthCond);
            if ((dayOfWeek == 0  && ( (firstDayOfMonth == 0 && moment(j.inserton).format('DD') > 1) || (secondDayOfMonth == 0 && moment(j.inserton).format('DD') > 2) || (firstDayOfMonth != 0 && secondDayOfMonth != 0))) || index === i.logged_hours.length - 1) { // Sunday or end of month
              // console.log( j.inserton + ` Weekly hours (Week ${Math.ceil(daysCounter / 5)}): ${weeklySumHero}`);
              temArrHours.push({'hours':weeklySumHero,'preHours':weeklySumMngr});
              temArrPrebilledHours.push({'preHours':weeklySumMngr});
              weeklySumHero = 0;
              weeklySumMngr = 0;
              daysCounter = 0;
              weekCountInMonth+=1;
            }
        });
        i.totalBillingDays = totalBillingDays;
        i.countHours = countHours;
        i.weeklyHours = temArrHours;
        i.weeklyPrebilled = temArrPrebilledHours;
        $scope.numOfWeeks = weekCountInMonth;
      });
      const numOfWeeks = $scope.numOfWeeks;
      $scope.prebilled = res;
      if (res) {
        let newResult = null, newResult1 = null, resHero = null;
        $scope.myDiary.datatable.map((o) => {
          o.destroy();
        });
        document.querySelectorAll("#myDiaryDataTableView thead tr th.weeks").forEach(o => o.remove());
        $scope.myDiary = {default: [], project: [], heroes: [], datatable: []};
        let res1 = $scope.$root.sort(res, "emp_first_name");
        $scope.myDiary.default = $scope.$root.sort(res1, "proj_name");
        newResult = res.map(o => o.proj_name + "~" + o.projectid).filter((v, i, s) => s.indexOf(v) === i).sort();
        newResult.forEach(o => {
          const proj = o.split("~");
          $scope.myDiary.project.push({name: proj[0], id: proj[1], data: res.filter(j => j.projectid === parseInt(proj[1]))});
        });
        newResult1 = res.map(o => o.emp_first_name + " " + o.emp_last_name + "-" + o.employeeid).filter((v, i, s) => s.indexOf(v) === i).sort();
        resHero = $scope.$root.sort(res, "projectid");
        newResult1.forEach(o => {
          const hero = o.split("-");
          $scope.myDiary.heroes.push({name: hero[0], id: hero[1], data: resHero.filter(j => j.employeeid === parseInt(hero[1]))});
        });
        $scope.tblheader = [];
        var headerLength = 1;
        var flags = [], output = [],inserton = [],weekly=[], l = res[0].logged_hours.length, i;
        for( i=0; i<l; i++) {
            if( flags[res[0].logged_hours[i].dates]) continue;
            flags[res[0].logged_hours[i].dates] = true;
            output.push(res[0].logged_hours[i].dates);
            inserton.push(res[0].logged_hours[i].inserton);
        }
        for (let k = 0 ; k < numOfWeeks; k++) {
          try {
            headerLength++;
            var node = document.createElement("th");
            var node2 = document.createElement("th");
            var textnode;
            var textnode2;
            let num0 = parseInt(k)+1;
            textnode = document.createTextNode('Week-'+num0);
            textnode2 = document.createTextNode('Week-'+num0);
            node.appendChild(textnode); 
            if($scope.filter.proj_id!=0){
              node2.appendChild(textnode2); 
            }
            document.querySelector("#myDiaryDataTableView thead tr").appendChild(node);
            node.setAttribute("class", "weeks");
            if($scope.filter.proj_id!=0){
                document.querySelector("#myDiaryDataTableView thead tr").appendChild(node2);
                node2.setAttribute("class", "weeks");
            }
          }
          catch (e) {
            console.error(e);
          }
        }

      $scope.$root.callDataTable("#myDiaryDataTableView", headerLength * 100, (t) => {
        // $scope.myDiary.datatable.push(t);
        $scope.dTable = t;
      },{orientation:'landscape'},{fixedColumns:{left:5}});

      document.getElementById('blackout').style.display = 'none';
      $scope.callConsolidated();
      

      vServices.callApi("invoice/singleInvoice?projId="+ $scope.filter.proj_id, "GET", {}).then(res => {
        if(res){
          $scope.invoiceData = res[0];
        }
      });
        
      }
      $scope.showBtn = true;
    };

    $scope.getWeekDaysOfMonth = (year, month, weekNumber, startDayOfWeek) => {
      if(startDayOfWeek==6 || startDayOfWeek==0){
        return 5;
      }
      const firstDayOfMonth = new Date(year, month - 1, 1);
      const firstWeekdayOfMonth = firstDayOfMonth.getDay();
      const daysInMonth = new Date(year, month, 0).getDate();
      const daysInFirstWeek = 7 - ((firstWeekdayOfMonth - startDayOfWeek + 7) % 7);
      const firstDayOfWeek = new Date(year, month - 1, 1 + daysInFirstWeek + (weekNumber - 2) * 7);
      let weekdaysInWeek = 0;
      var cnt = 7 - (startDayOfWeek - 1);// 7-6-1
      for (let i = 0; i < cnt; i++) {
          const day = new Date(firstDayOfWeek.getTime() + (i * 24 * 60 * 60 * 1000));
           if (day.getMonth() === month - 1 && day.getDay() >= 1 && day.getDay() <= 5) { // Monday to Friday
              weekdaysInWeek++;
          } 
      }
      return weekdaysInWeek;
  }

  $scope.getSaturdaysAndSundays = (year, month) => {
    const daysInMonth = new Date(year, month, 0).getDate();
    const results = [];
  
    for (let day = 1; day <= daysInMonth; day++) {
      const date = new Date(year, month - 1, day);
      if (date.getDay() === 0 || date.getDay() === 6) {
        results.push(date);
      }
    }
  
    return results;
  }

    const getData = (f, t, h,r,pid) => {
    f = moment($scope.filter.monthyear).clone().startOf('month').format('DD-MM-YYYY');
    t = moment($scope.filter.monthyear).clone().endOf('month').format('DD-MM-YYYY');
      vServices.callApi("mydiary/unfilledclone?date=" + f + "&todate=" + t + "&minHours=" + h + "&rc_name=" + r + "&proj_id="+ pid, "GET", {}).then(res => {
        if(res){
          $scope.tempArry = res;
          convertDataForMyDiaryWeekly(res);
        }
        // if(res==null){
        //   $scope.showLoader = false;
        //   $scope.tempArry = [];
        //   $scope.myDiary.default = [];
        //   $scope.tblheader = [];
        //   if($scope.dTable)$scope.dTable.destroy();
        //   $scope.$root.callDataTable("#myDiaryDataTableView", 100, (t) => {
        //     $scope.dTable = t;
        //   },{orientation:'landscape'},{fixedColumns:{left:5}});
        //   $scope.showBtn=true;
        // }
      });
    }

    $scope.dateChanged = (first = false) => {
      if (!first) {
        $scope.showLoader = true;
        $scope.showBtn = false;
        $scope.showLockDiv = $scope.filter.project.id > 0 ? true : false;
      if (!$scope.filter.fromDate) toastr.error("Please provide valid FromDate");
        else if (!$scope.filter.toDate) toastr.error("Please provide valid toDate");
      else getData($scope.filter.fromDate, $scope.filter.toDate, $scope.filter.minHours,$scope.filter.rc_name,$scope.filter.proj_id);
      }
    };


    $scope.projectByRevenue = (rev_id) => {
      vServices.callApi("myDiary/allmyDiaryProjects?rev_id="+ rev_id, "GET", {}).then(res => convertDataForProject(res));
    };

    $scope.changeConsolidatedData = () =>{
      $scope.callConsolidated();
    }

    $scope.callConsolidated = () =>{
      var cData = $scope.myDiary.default;
      let tData = [];
      // console.log(cData);
      tData = cData.map(x=>{
        return {
          'empId': x.employeeid,
          'empName' : x.emp_first_name + ' ' + x.emp_last_name,
          'loggedhour' : x.logged_hours
        }
      });
      tData.forEach(i=>{
        var totalDays = 0;
        var totalHours = 0;
          i.loggedhour.forEach(x=>{
            var temp=0;
            const dayOfWeek = moment(x.inserton).day();
            const leaves = x.logtype.split(',');
            const isLorH = leaves.includes('16') || leaves.includes('17') || leaves.includes('22') || leaves.includes('23') ? false : true;
            if(x.prebilled>0 && !x.logtype.includes('24') && isLorH && dayOfWeek!=0 && dayOfWeek!=6){
              totalDays+=1;
              temp=x.prebilled?parseFloat(x.prebilled):0;
            }else if(x.prebilled>0 && x.logtype.includes('24') && isLorH && dayOfWeek!=0 && dayOfWeek!=6){
              totalDays+=0.5;
              temp=x.prebilled?parseFloat(x.prebilled):0;
            }else{
              totalDays+=0;
            }
            // temp=x.prebilled && !isLorH ? parseFloat(x.prebilled) : 0;
            totalHours+=temp;
          })
          i.totalDays = totalDays;
          i.totalMonthHours = totalHours;
          vServices.callApi("myDiary/getHeroBillingDetails?projId="+ $scope.filter.proj_id + '&empId='+i.empId, "GET", {}).then(res => {
            if(res.length>0){
              if(res[0].billing_type){
                i.billing_rate = res[0].billing_rate  ? parseFloat(res[0].billing_rate) : 0;
                i.total = res[0].billing_type=='1' ? parseFloat(i.billing_rate) * parseFloat(totalHours) : parseFloat(i.billing_rate) * parseFloat(totalDays);
              }else{
                i.billing_rate = 0;
                i.total = 0;
              }
              i.billing_type = res[0].billing_type;
              $scope.billingType = res[0].billing_type=='1' ? 'Hourly' : 'Daily';
            }else{
              i.billing_rate = 0;
              i.total = 0;
              i.billing_type = '1';
              $scope.billingType = 'Hourly';
            }
          });
      });
      $scope.consolidatedData = tData;
    }
    const init = () => {
      // getData();

      vServices.callApi("/account/all_revenue_centers", "GET", {}).then(function (res) {
        if (res && res.length > 0) {
        $scope.revenueCenters = res;
        }
      });

    };

    $scope.PreBilledSave = () => {
      if (confirm("Do you really want to save and update the data !")) {
        $scope.prebilled.forEach(i=>{
          i.logged_hours.forEach(j=>{
            j.emp_id = i.employeeid;
            j.proj_id = $scope.filter.proj_id;
          });
        });
        $scope.showLoader = true;
        $scope.showBtn = false;
        vServices.callApi("mydiary/updatePrebilled","POST", {myval: JSON.stringify($scope.prebilled)}).then(function (res) {
          if(res){
            toastr.success('Data updated successfully');
            $scope.showLoader = false;
            $scope.showBtn = true;
            $scope.callConsolidated();
          }
        })
      }
    }

    $scope.PreBilledSaveWeekly = () => {
      new Promise((resolve)=>{
        $scope.prebilled.forEach((i,indexParent)=>{
          let globalObj = [];
            i.weeklyHours.forEach((w,y)=>{
              try {
             
              const weeklyHoursArr = [];
              const hr = parseFloat(w.preHours);
              var weekDay;
              if(y==0){
                weekDay = moment($scope.filter.monthyear).day() ?  moment($scope.filter.monthyear).day() : 1;
              }else{
                weekDay = 1;
              }
              let iterate = y + 1;
              let days = $scope.getWeekDaysOfMonth(moment($scope.filter.monthyear).format('YYYY'),moment($scope.filter.monthyear).format('MM'),iterate,weekDay);
                for(let z=0;z<days;z++){
                  try {
                    console.log(i.emp_first_name, hr);
                    let dayHours = Math.round(parseFloat(hr) / parseFloat(days));
                    let obj = {'days':z+1,'weekDay':y+1,'dayHours':dayHours};
                    globalObj.push(obj);
                    weeklyHoursArr[z]= obj;

                  } catch (error1) {console.error(error1);}
                }
              w.WeeklyHoursData = weeklyHoursArr;
            } catch (error2) {console.error(error2);}
            });
            let dynVar=0;
            i.overAllWeeklyData = globalObj;
            i.logged_hours.forEach(j=>{
              try {
                j.emp_id = i.employeeid;
                j.proj_id = $scope.filter.proj_id;
                if(moment(j.inserton).day()==0 || moment(j.inserton).day()==6){
                  j.prebilled = 0;
                }else{
                  if(dynVar==globalObj.length){}
                    else{
                      j.prebilled = globalObj[dynVar].dayHours;
                      dynVar++;}
                }
              } catch (error3) {console.error(error3);}
            });
            if(indexParent===$scope.prebilled.length-1){
              setTimeout(()=>{
                resolve($scope.prebilled);
              },2000);
            }
        });
      }).then((result)=>{
        if (confirm("Do you really want to save and update the data !")) {
          $scope.showLoader = true;
          $scope.showBtn = true;
          getJson(JSON.stringify(result)).then((_data) => {
            vServices.callApi("mydiary/updatePrebilled2","POST", {myval: JSON.stringify(_data)}).then(function (res) {
              if(res){
                toastr.success('Data updated successfully');
                $scope.showLoader = false;
                $scope.showBtn = true;
                $scope.callConsolidated();
              }
            })
          }).catch((err) => {
              console.log(25,err);
          });
  
        }
      },5000)
      
    },

    $scope.getDatesOfMonthAndWeekNumber = (year, month, weekNumber) => {
      const dates = [];
      console.log(year,weekNumber,month);
      let date = new Date(year, month, 1);
      while (date.getMonth() === month) {
        if (date.getDay() === 1 && Math.ceil(date.getDate() / 7) === weekNumber) {
          dates.push(new Date(date));
        }
        date.setDate(date.getDate() + 1);
      }
      return dates;
    }

    $scope.getSingleWeekly = (array,weekNumber,preIndex) => {
      $scope.showLoader = true;
      document.getElementById('blackout').style.display = 'block';
      array.forEach((i,indexParent)=>{
        let globalObj = [];
            const weeklyHoursArr = [];
            const hr = parseFloat(i.preHours);
            var weekDay = moment($scope.filter.monthyear).day();
            const dates = $scope.getDatesOfMonthAndWeekNumber(
              moment($scope.filter.monthyear).format('YYYY'),
              moment($scope.filter.monthyear).format('MM')-1, 
              weekNumber);
            // const dates = $scope.getDatesOfMonthAndWeekNumber(2023,3,1);
            let days = $scope.getWeekDaysOfMonth(moment($scope.filter.monthyear).format('YYYY'),moment($scope.filter.monthyear).format('MM'),weekNumber,weekDay);
            console.log(dates);  
            for(let z=0;z<days;z++){
                  console.log(hr);
                  let dayHours = Math.round(parseFloat(hr) / parseFloat(days));
                  let obj = {'days':z+1,'emp_id':i.emp_id,'proj_id':i.proj_id,'weekDay':weekNumber,'prebilled':dayHours,'inserton':moment(dates[0],'YYYY-MM-DD').add(z, 'days').format('YYYY-MM-DD')};
                  globalObj.push(obj);
                  weeklyHoursArr[z]= obj;
              }
            i.WeeklyHoursData = weeklyHoursArr;
          i.overAllWeeklyData = globalObj;
          i.logged_hours = globalObj;
      })
        $scope.showLoader = true;
        // $scope.showBtn = true;
        getJson(JSON.stringify(array)).then((_data) => {
          console.log(_data);
          vServices.callApi("mydiary/updatePrebilled2","POST", {myval: JSON.stringify(_data)}).then(function (res) {
            if(res){
              toastr.success('Data updated successfully');
              $scope.showLoader = false;
              document.getElementById(preIndex).style = 'none';
              document.getElementById(preIndex).className = " form-control text-bold  is-valid ng-not-empty ng-touched ";  
              $scope.dateChanged(false);
            }
          })
        })
    }



    $scope.OnChangePrebilled = (empId,pIndex,proj_id,week,mngr_hours) =>{
      
      let preIndex = 'prebilled' + empId + pIndex;
      var mngrVal = mngr_hours ? parseFloat(mngr_hours) : 0;
      let preVal = document.getElementById(preIndex).value;
      if(mngrVal > 9){
        document.getElementById(preIndex).style.border = '2px solid rgb(122 123 123)';
        document.getElementById(preIndex).style.backgroundImage = `url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='rgb(122 123 123)' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>")`;
        document.getElementById(preIndex).style.backgroundRepeat = 'no-repeat';
        document.getElementById(preIndex).style.backgroundPosition = 'center right calc(0.375em + 0.1875rem)';
        document.getElementById(preIndex).style.backgroundSize = 'calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)';
        var arr = [{'emp_id':empId,'proj_id':proj_id,'preHours':parseFloat(mngr_hours)}];
        $scope.getSingleWeekly(arr,week,preIndex);
      }else{
        document.getElementById(preIndex).style.border = '2px solid #f30d0d';
      }
    }
    init();

    const getJson = (jsonArr) => {
      const final_json = {};
      return new Promise((resolve, reject) => {
          let json = JSON.parse(jsonArr);
          for (let i = 0; i < json.length; i++) {
              const jsonElement = json[i];
              for (let j = 0; j < jsonElement.logged_hours.length; j++) {
                  const logged_hour = jsonElement.logged_hours[j];
                  const prebilled = logged_hour.prebilled ? logged_hour.prebilled : 0;
                  if(final_json[prebilled] === undefined){
                      final_json[prebilled] = [];
                  }
  
                  const uuid = `${logged_hour.inserton}_${logged_hour.proj_id}_${logged_hour.emp_id}`;
                  if(final_json[prebilled].indexOf() === -1) {
                      final_json[prebilled].push(uuid);
                  }
                  // console.log(logged_hour.prebilled,"\t", logged_hour.inserton,logged_hour.proj_id,logged_hour.emp_id);
                  if(j === jsonElement.logged_hours.length-1 && i === json.length-1){
                      // console.log("done");
                      resolve(final_json);
                  }
              }
          }
      });
    }

  }]);
