import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { ActivityEmployee, DeleteFormActivity, ResponseDataGetActivityEmployee } from '../../../../interfaces/personal-managment/employee.interface';
import { FormControl } from '@angular/forms';
import { ResourcesService, ResponseData } from '../../../../services/resources.service';
import { ActivatedRoute, Router } from '@angular/router';
import { EncService } from '../../../../services/enc.service';
import { MatDialog } from '@angular/material/dialog';
import { EmployeeService } from '../../../../services/personal-management/employee.service';
import { lastValueFrom } from 'rxjs';
import moment, { MomentInput, Moment } from 'moment';
import { HttpErrorResponse } from '@angular/common/http';
import { MAT_MOMENT_DATE_ADAPTER_OPTIONS, MomentDateAdapter } from '@angular/material-moment-adapter';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
import { MatDatepicker } from '@angular/material/datepicker';
import { FormScheduleActivityComponent } from './form-schedule-activity/form-schedule-activity.component';
import { AlertComponent } from '../../../resources/dialogs/alert/alert.component';

@Component({
    selector: 'app-schedule-activities',
    templateUrl: './schedule-activities.component.html',
    styleUrl: './schedule-activities.component.css',
    providers: [
        {
            provide: DateAdapter,
            useClass: MomentDateAdapter,
            deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS],
        },
        { provide: MAT_DATE_FORMATS, useValue: {
                parse: {
                    dateInput: 'MMMM YYYY',
                },
                display: {
                    dateInput: 'MMMM YYYY',
                    monthYearLabel: 'MMM YYYY',
                    dateA11yLabel: 'LL',
                    monthYearA11yLabel: 'MMMM YYYY',
                },
            } },
    ],
    standalone: false
})
export class ScheduleActivitiesComponent implements OnInit {
  public isLoading: boolean;
  public isLoadingForm: boolean;
  public idEmployee: string;

  public dataSource: MatTableDataSource<ActivityEmployee>;
  public displayedColumns: Array<string>;
  public columnsToDisplay: Array<string>;
  public arrScheduleActivities: Array<ActivityEmployee>;

  public weekShift: number;

  public arrWeek:Array<string> = ['D','L','M','X','J','V','S'];
  public arrWeekName:Array<string> = ['Dom','Lun','Mar','Mie','Jue','Vie','Sab'];
  public startDateWeek: Date;
  public endDateWeek!: Date;

  public columnsToDisplayHeader: Array<string>;
  public headerGroup2: { month : string, columns: number };
  public headerGroup3: { month : string, columns: number };

  public isLoadCount: number;
  public startColumnWeek: number;
  public dateSelected = new FormControl(moment());

  public currentDate:Date;
  public dateWeekSelected:Date;
  public isClicBtnFilter: boolean;

  constructor(
    public resourcesService: ResourcesService,
    private _activatedRouter: ActivatedRoute,
    private _encService: EncService,
    private _dialog: MatDialog,
    private _router: Router,
    private ref: ChangeDetectorRef,
    private _employeeService: EmployeeService,
  ) {
    this.isLoading = false;
    this.isLoadingForm = false;
    this.idEmployee = '';

    this.weekShift = 0;

    this.dataSource = new MatTableDataSource<ActivityEmployee>();
    this.displayedColumns = ['ID','Actividad','Periodo','Tipo de Actividad','Nivel', 'Acciones','D','L','M','X','J','V','S'];
    this.columnsToDisplay = this.displayedColumns.slice()
    this.columnsToDisplayHeader = ['header-row-first-group'];
    this.headerGroup2 = { month: '', columns: 0 };
    this.headerGroup3 = { month: '', columns: 0 };

    this.isLoadCount = 0;
    this.startColumnWeek = 6;

    this.arrScheduleActivities = [];

    this.currentDate = new Date();
    this.dateWeekSelected = new Date();

    this.startDateWeek = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), this.currentDate.getDate() - this.currentDate.getDay());
    this.endDateWeek = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), (this.currentDate.getDate() - this.currentDate.getDay()) + 6);

    this.isClicBtnFilter = false;
  }

  async ngOnInit() {
    this.isLoading = true;
    await this.getDataEmployee();
    await this.getScheduleActivitiesByEmployee();
    this.isLoading = false;

    this.dateSelected.valueChanges.subscribe((valueDate) => {
      if (valueDate !== null && !this.isClicBtnFilter === true) {
        let selectedDate: Date = valueDate.toDate();
        this.dateWeekSelected = new Date( selectedDate.getFullYear(), selectedDate.getMonth(), 1 ) ;
        this.setValueRow();
      }
    });
  }

  private async getDataEmployee() {
    let encEmployee = this._activatedRouter.snapshot.paramMap.get('idEmployee');
    if (encEmployee === null) {
      this.resourcesService.openSnackBar(`Ocurrío un error al obtener el ID del empleado.`);
      this._router.navigate(['/sam/GPRS/GEPE/GEPE']);
      return;
    }    
    this.idEmployee = await this._encService.decrypt(encEmployee);
  }

  public async getScheduleActivitiesByEmployee() {
    this.isLoading = true;
    const encEmployee: string = await this._encService.encrypt(this.idEmployee);
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._employeeService.getScheduleActivitiesByEmployee(encEmployee, user, line)).then(
      (responseData: ResponseDataGetActivityEmployee) => {
        if (!responseData.error) {
          this.arrScheduleActivities = responseData.response;
          this.dataSource.data = responseData.response;
          this.setValueRow();

          this.dateSelected.setValue(moment());
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getScheduleActivitiesByEmployee();
        }
      }
    );
    this.isLoading = false;
  }

  public setValueRow() {
    this.columnsToDisplayHeader = ['header-row-first-group'];
    this.headerGroup2.month = '';
    this.headerGroup2.columns = 0;
    this.headerGroup3.month = '';
    this.headerGroup3.columns = 0;

    this.arrWeek.forEach((week:string, index:number) => {

      let currentWeek:number = this.dateWeekSelected.getDay();
      let currentDay:number = this.dateWeekSelected.getDate();
      let currentMonth:number = this.dateWeekSelected.getMonth();
      let currentYear:number = this.dateWeekSelected.getFullYear();

      // Realiza las operaciones necesarias para obtener las fechas de Domingo a Sábado de la semana seleccionada.
      if ( index < currentWeek ) {
        let daysAgo: number = currentWeek - index;
        currentDay = currentDay - daysAgo;
      } else if ( index >  currentWeek ) {
        let daysAgo: number = index - currentWeek ;
        currentDay = currentDay + daysAgo;
      } 
      let dateWeek: Date = new Date(currentYear, currentMonth, currentDay);
      
      // Asigna el día y la semana al nombre de la columna
      let columnNew = `${this.arrWeekName[dateWeek.getDay()]} ${dateWeek.getDate()}`;
      this.displayedColumns[index + this.startColumnWeek] = columnNew;

      this.displayedColumns = this.displayedColumns;
      this.columnsToDisplay = this.displayedColumns.slice();
      // this.ref.detectChanges();
          
      let headerMonth = `${ this.resourcesService.arrMonthLabel[dateWeek.getMonth()] } - ${dateWeek.getFullYear()}`;

      // Obtiene la fecha inicial y final de la semana mostrada en la interfaz
      if (index === 0) {
        this.headerGroup2.month = headerMonth;
        this.columnsToDisplayHeader.push('header-row-second-group');
        this.startDateWeek = dateWeek;
      } else if (index === 6){
        this.endDateWeek = dateWeek;
      }            

      if (this.headerGroup2.month === headerMonth) {
        this.headerGroup2.columns += 1;
      } else {
        if (this.headerGroup3.month === '') {
          this.columnsToDisplayHeader.push('header-row-third-group');
        }
        this.headerGroup3.month = headerMonth;
        this.headerGroup3.columns += 1; 
      }

      this.isLoadCount += 1;
    });
    this.ref.detectChanges();
    
    this.isClicBtnFilter = false;

    // Se modifica el filtro de los meses sin que se vuelva a ejecutar el mismo método.
    this.isClicBtnFilter = true;
    let dateToMoment: Date = new Date(this.endDateWeek.getFullYear(), this.endDateWeek.getMonth(), 1);
    let momentInputSelected:MomentInput = moment(dateToMoment);
    this.dateSelected.setValue( momentInputSelected );
    this.isClicBtnFilter = false;

    this.setColorActivityTable();
  }

  private async setColorActivityTable() {
    this.isLoadingForm = true;
    this.arrScheduleActivities.map((activityEmployeeElement: ActivityEmployee, rowEmployee: number) => {
      if (activityEmployeeElement.PERIODICIDAD === 'NR') {
        let fechaInicio: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);
        let fechaFinal: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_FINAL);
        let diffDays = (fechaFinal.getTime() - fechaInicio.getTime()) / (1000*60*60*24) + 1;
        
        for (let days = 0; days < diffDays; days++) {
          let dayDifference: Date = new Date( fechaInicio.getFullYear(), fechaInicio.getMonth(), fechaInicio.getDate() + days );
          this.arrWeek.map((week: string, index: number) => {
            let dateOfWeek: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
            
            if (dateOfWeek.getTime() === dayDifference.getTime()) {
              this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
            }          
          });
        }

      } else if (activityEmployeeElement.PERIODICIDAD === 'SE') {
        let fechaInicio: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);
        let weekSelect = fechaInicio.getDay();
        this.arrWeek.map((week: string, index: number) => {
          let compareDate: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
          if (weekSelect === index && compareDate >= fechaInicio) {
            this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
          } else {
            this.setColorCell(index, rowEmployee, "#FFFFFF");
          }
        })
      } else if (activityEmployeeElement.PERIODICIDAD === 'ME') {
        let fechaInicio: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);
        let dateCalendar: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);
        this.arrWeek.map((week: string, index: number) => {
          let compareDate: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
          let diffMonth: number = fechaInicio.getMonth() - compareDate.getMonth();
          dateCalendar.setMonth(fechaInicio.getMonth() - diffMonth);
          if (compareDate.getTime() === dateCalendar.getTime() && compareDate >= fechaInicio) {
            this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
          } else {
            this.setColorCell(index, rowEmployee, "#FFFFFF");
          }
        });
      } else if (activityEmployeeElement.PERIODICIDAD === 'AN') {
        let fechaInicio: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);

        this.arrWeek.map((week: string, index: number) => {
          let compareDate: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
          if (compareDate.getDate() === fechaInicio.getDate() && compareDate.getMonth() === fechaInicio.getMonth() && compareDate >= fechaInicio) {
            this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
          } else {
            this.setColorCell(index, rowEmployee, "#FFFFFF");
          }
        });
      } else if (activityEmployeeElement.PERIODICIDAD === 'TD') {
        let fechaInicio: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);
        this.arrWeek.map((week: string, index: number) => {
          let compareDate: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
          if ( compareDate >= fechaInicio ) {
            this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
          } else {
            this.setColorCell(index, rowEmployee, "#FFFFFF");
          }
        });
      } else if (activityEmployeeElement.TIPO_ACTIVIDAD === 'MC' || activityEmployeeElement.TIPO_ACTIVIDAD === 'MP') {
        let fechaInicio: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);
        this.arrWeek.map((week: string, index: number) => {
          let compareDate: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
          if (fechaInicio.getTime() === compareDate.getTime()) {
            this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
          } else {
            this.setColorCell(index, rowEmployee, "#FFFFFF");
          }
        });
      } else if (activityEmployeeElement.PERIODICIDAD === 'PE' && activityEmployeeElement.PERIODICIDAD_PERSONALIZADA !== null) {
        let startDate:Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);

        let strPersonalized = activityEmployeeElement.PERIODICIDAD_PERSONALIZADA;
        let arrPersonalized = JSON.parse(strPersonalized);
        
        let endsAt:string = arrPersonalized['endsAt'];
        let arrEndsAt:Array<string> = endsAt.split('|');

        let repeatEvery:string = arrPersonalized['repeatEvery'];
        let arrRepeatEvery:Array<string> = repeatEvery.split('|');
        
        let numberRepeat:number = parseInt(arrRepeatEvery[0]);
        let typeRepeat:number = parseInt(arrRepeatEvery[1]);
        
        let repeatOn = arrPersonalized['repeatOn'];
        
        let isNever: string = arrEndsAt[0];
        let endDate:Date = this.resourcesService.formatStrDateToDate2(arrEndsAt[1]);
        let repeatEnd:number = parseInt(arrEndsAt[2]);      
        
        
        switch (typeRepeat) {
          case 0:
            this.arrWeek.map((week: string, index: number) => {
              let compareDate: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
              let diffDays:number = (compareDate.getTime() - startDate.getTime()) / (1000*60*60*24);
              let resp:number = diffDays / numberRepeat;

              if (
                (compareDate >= startDate && Number.isInteger(resp)) && 
                (
                  (isNever === 'N') || 
                  (isNever === 'O' && compareDate < endDate) || 
                  (isNever === 'A' && resp <= repeatEnd)
                )
              ) {
                this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
              } else {
                this.setColorCell(index, rowEmployee, "#FFFFFF");
              }

            });
            break;
          case 1:
            let dateSun: Date|null = null;
            let dateMon: Date|null = null;
            let dateTue: Date|null = null;
            let dateWed: Date|null = null;
            let dateThu: Date|null = null;
            let dateFri: Date|null = null;
            let dateSat: Date|null = null;            
            
            // Se obtienen las primeras fechas de los días seleccionados
            for (let index = 0; index < 7; index++) {
              let initDate = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);
              
              let startDateWeek = initDate.getDay() + index;

              if (startDateWeek > 6) {
                startDateWeek = startDateWeek - 7;
              }
              
              if (startDateWeek === 0 && repeatOn["sun"]) {
                dateSun = initDate;
                dateSun.setDate(initDate.getDate() + index);
              }
              if (startDateWeek === 1 && repeatOn["mon"]) {
                dateMon = initDate;
                dateMon.setDate(initDate.getDate() + index);
              }
              if (startDateWeek === 2 && repeatOn["tue"]) {
                dateTue = initDate;
                dateTue.setDate(initDate.getDate() + index);
              }
              if (startDateWeek === 3 && repeatOn["wed"]) {
                dateWed = initDate;
                dateWed.setDate(initDate.getDate() + index);
              }
              if (startDateWeek === 4 && repeatOn["thu"]) {
                dateThu = initDate;
                dateThu.setDate(initDate.getDate() + index);
              }
              if (startDateWeek === 5 && repeatOn["fri"]) {
                dateFri = initDate;
                dateFri.setDate(initDate.getDate() + index);
              }
              if (startDateWeek === 6 && repeatOn["sat"]) {
                dateSat = initDate;
                dateSat.setDate(initDate.getDate() + index);
              }   

            }
            
            // Se obtiene la cantidad de días de diferencia entre cada día de la semana
            let betweenDays: number = numberRepeat * 7;

            // Se obtienen los días de la semana
            this.arrWeek.map((week: string, index: number) => {

              // Se itera la fecha de la semana mostrada en la interfaz
              let compareDate: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
              
              // Se verifica que solo los días después de la fecha de inicio sean mostrados
              if (compareDate >= startDate) {
                
                // Se verifica si fue seleccionado el Domingo
                if (repeatOn["sun"] && index === 0 && dateSun !== null) {
                  // Se obtiene la diferencia de días del primer Domingo disponible después de la fecha de inicio con el Domingo mostrado en la interfaz
                  let diffDays:number = (compareDate.getTime() - dateSun.getTime()) / (1000*60*60*24);
                  // Si la fecha del Domingo es multiplo de los días de la primera fecha del Domingo entonces se ilumina.
                  let resp:number = diffDays / betweenDays;
                  if (Number.isInteger(resp) && 
                    (
                      (isNever === 'N') || 
                      (isNever === 'O' && compareDate < endDate) || 
                      (isNever === 'A' && resp <= repeatEnd)
                    )
                  ) {
                    this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
                  } else {
                    this.setColorCell(index, rowEmployee, "#FFFFFF");
                  }
                }

                // Se verifica si fue seleccionado el Lunes
                if (repeatOn["mon"] && index === 1 && dateMon !== null) {
                  // Se obtiene la diferencia de días del primer Lunes disponible después de la fecha de inicio con el Lunes mostrado en la interfaz
                  let diffDays:number = (compareDate.getTime() - dateMon.getTime()) / (1000*60*60*24);
                  // Si la fecha del Lunes es multiplo de los días de la primera fecha del Lunes entonces se ilumina.
                  let resp:number = diffDays / betweenDays;
                  if (Number.isInteger(resp) && 
                    (
                      (isNever === 'N') || 
                      (isNever === 'O' && compareDate < endDate) || 
                      (isNever === 'A' && resp <= repeatEnd)
                    )
                  ) {
                    this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
                  } else {
                    this.setColorCell(index, rowEmployee, "#FFFFFF");
                  }
                }

                // Se verifica si fue seleccionado el Martes
                if (repeatOn["tue"] && index === 2 && dateTue !== null) {
                  // Se obtiene la diferencia de días del primer Martes disponible después de la fecha de inicio con el Martes mostrado en la interfaz
                  let diffDays:number = (compareDate.getTime() - dateTue.getTime()) / (1000*60*60*24);
                  // Si la fecha del Martes es multiplo de los días de la primera fecha del Martes entonces se ilumina.
                  let resp:number = diffDays / betweenDays;
                  if (Number.isInteger(resp) && 
                    (
                      (isNever === 'N') || 
                      (isNever === 'O' && compareDate < endDate) || 
                      (isNever === 'A' && resp <= repeatEnd)
                    )
                  ) {
                    this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
                  } else {
                    this.setColorCell(index, rowEmployee, "#FFFFFF");
                  }
                }

                // Se verifica si fue seleccionado el Miercoles
                if (repeatOn["wed"] && index === 3 && dateWed !== null) {
                  // Se obtiene la diferencia de días del primer Miercoles disponible después de la fecha de inicio con el Miercoles mostrado en la interfaz
                  let diffDays:number = (compareDate.getTime() - dateWed.getTime()) / (1000*60*60*24);
                  // Si la fecha del Miercoles es multiplo de los días de la primera fecha del Miercoles entonces se ilumina.
                  let resp:number = diffDays / betweenDays;
                  if (Number.isInteger(resp) && 
                    (
                      (isNever === 'N') || 
                      (isNever === 'O' && compareDate < endDate) || 
                      (isNever === 'A' && resp <= repeatEnd)
                    )
                  ) {
                    this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
                  } else {
                    this.setColorCell(index, rowEmployee, "#FFFFFF");
                  }
                }

                // Se verifica si fue seleccionado el Jueves
                if (repeatOn["thu"] && index === 4 && dateThu !== null) {
                  // Se obtiene la diferencia de días del primer Jueves disponible después de la fecha de inicio con el Jueves mostrado en la interfaz
                  let diffDays:number = (compareDate.getTime() - dateThu.getTime()) / (1000*60*60*24);
                  // Si la fecha del Jueves es multiplo de los días de la primera fecha del Jueves entonces se ilumina.
                  let resp:number = diffDays / betweenDays;
                  if (Number.isInteger(resp) && 
                    (
                      (isNever === 'N') || 
                      (isNever === 'O' && compareDate < endDate) || 
                      (isNever === 'A' && resp <= repeatEnd)
                    )
                  ) {
                    this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
                  } else {
                    this.setColorCell(index, rowEmployee, "#FFFFFF");
                  }
                }

                // Se verifica si fue seleccionado el Viernes
                if (repeatOn["fri"] && index === 5 && dateFri !== null) {
                  // Se obtiene la diferencia de días del primer Viernes disponible después de la fecha de inicio con el Viernes mostrado en la interfaz
                  let diffDays:number = (compareDate.getTime() - dateFri.getTime()) / (1000*60*60*24);
                  // Si la fecha del Viernes es multiplo de los días de la primera fecha del Viernes entonces se ilumina.
                  let resp:number = diffDays / betweenDays;
                  if (Number.isInteger(resp) && 
                    (
                      (isNever === 'N') || 
                      (isNever === 'O' && compareDate < endDate) || 
                      (isNever === 'A' && resp <= repeatEnd)
                    )
                  ) {
                    this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
                  } else {
                    this.setColorCell(index, rowEmployee, "#FFFFFF");
                  }
                }

                // Se verifica si fue seleccionado el Sábado
                if (repeatOn["sat"] && index === 6 && dateSat !== null) {
                  // Se obtiene la diferencia de días del primer Sábado disponible después de la fecha de inicio con el Sábado mostrado en la interfaz
                  let diffDays:number = (compareDate.getTime() - dateSat.getTime()) / (1000*60*60*24);
                  // Si la fecha del Sábado es multiplo de los días de la primera fecha del Sábado entonces se ilumina.
                  let resp:number = diffDays / betweenDays;
                  if (Number.isInteger(resp) && 
                    (
                      (isNever === 'N') || 
                      (isNever === 'O' && compareDate < endDate) || 
                      (isNever === 'A' && resp <= repeatEnd)
                    )
                  ) {
                    this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
                  } else {
                    this.setColorCell(index, rowEmployee, "#FFFFFF");
                  }
                }
              }
              
            });
            break;
          case 2:

            let fechaInicio: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);
            let dateCalendar: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);

            this.arrWeek.map((week: string, index: number) => {
              let compareDate: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
              
              let momentDateStart = moment(fechaInicio);
              let momentDateCompare = moment(compareDate);

              let diffMonth = momentDateCompare.diff(momentDateStart, 'months');
              dateCalendar.setMonth(fechaInicio.getMonth() + diffMonth);
              let resp:number = diffMonth / numberRepeat;

              if ((compareDate >= fechaInicio && compareDate.getDate() === dateCalendar.getDate() && Number.isInteger(resp))) {
                if (
                  (
                    (isNever === 'N') || 
                    (isNever === 'O' && compareDate < endDate) || 
                    (isNever === 'A' && resp < repeatEnd)
                  )
                ) {
                  this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
                } else {
                  this.setColorCell(index, rowEmployee, "#FFFFFF");
                }
              }
              
            });

            break;
          case 3:
            let fechaInicioYear: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);
            let dateCalendarYear: Date = this.resourcesService.formatStrDateToDate(activityEmployeeElement.FECHA_INICIO);

            this.arrWeek.map((week: string, index: number) => {
              let compareDate: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
              
              let momentDateStart = moment(fechaInicioYear);
              let momentDateCompare = moment(compareDate);

              let diffYears = momentDateCompare.diff(momentDateStart, 'years');
              dateCalendarYear.setFullYear(fechaInicioYear.getFullYear() + diffYears);
              let resp:number = diffYears / numberRepeat;              
              if (
                ( 
                  compareDate >= fechaInicioYear && 
                  compareDate.getDate() === dateCalendarYear.getDate() && 
                  compareDate.getMonth() === dateCalendarYear.getMonth() && 
                  Number.isInteger(resp)
                ) 
                && 
                (
                  (isNever === 'N') || 
                  (isNever === 'O' && compareDate < endDate) || 
                  (isNever === 'A' && resp < repeatEnd)
                )
              ) {
                this.setColorCell(index, rowEmployee, activityEmployeeElement.COLOR);
              } else {
                this.setColorCell(index, rowEmployee, "#FFFFFF");
              }
            });
            break;
        }
      }
    });
    
    this.arrWeek.map((week: string, index: number) => {
      let compareDate: Date = new Date( this.startDateWeek.getFullYear(), this.startDateWeek.getMonth(), this.startDateWeek.getDate() + index );
      if ( 
        this.currentDate.getFullYear() === compareDate.getFullYear() &&
        this.currentDate.getMonth() === compareDate.getMonth() &&
        this.currentDate.getDate() === compareDate.getDate()
        ) {        
          const rowId = document.getElementById(`row_${index + this.startColumnWeek}`);        
        if (rowId !== null) {
          rowId.style.color = "#C79100";
        }
      } else {
        const rowId = document.getElementById(`row_${index + this.startColumnWeek}`);
        if (rowId !== null) {
          rowId.style.color = "rgba(0, 0, 0, 0.87)";
        }
      }
    });
    
    this.ref.detectChanges();
    this.isLoadingForm = false;
  }

  private setColorCell( col: number, row: number, color: string ) {
    const rowId = document.getElementById(`cell_${col + this.startColumnWeek}_${row}`);
    if (rowId !== null) {
      rowId.style.backgroundColor = color;
    }
  }

  public reloadCalendar(sign:string) {
    this.isLoadCount = 0;
    this.headerGroup2.month = '';
    this.headerGroup2.columns = 0;
    this.headerGroup3.month = '';
    this.headerGroup3.columns = 0;
    this.columnsToDisplayHeader = ['header-row-first-group'];

    if (sign === '+') {
      this.dateWeekSelected.setDate(this.dateWeekSelected.getDate() + 7);
    } else {
      this.dateWeekSelected.setDate(this.dateWeekSelected.getDate() - 7);
    }

    this.setValueRow();
  }

  public setMonthAndYear(normalizedMonthAndYear: Moment, datepicker: MatDatepicker<Moment>) {
    const ctrlValue = this.dateSelected.value!;
    ctrlValue.month(normalizedMonthAndYear.month());
    ctrlValue.year(normalizedMonthAndYear.year());
    this.dateSelected.setValue(ctrlValue);
    datepicker.close();
  }

  public async openForm(typeForm: string, activityEmployee?:ActivityEmployee) {

    let idActivity: string | null = null;
    if (activityEmployee !== undefined && activityEmployee.ID_ACTIVIDAD !== undefined) {
      idActivity = activityEmployee.ID_ACTIVIDAD
    }

    this._dialog.open(FormScheduleActivityComponent, {
      disableClose: true,
      width: '650px',
      maxWidth: '650px',
      data: {
        typeForm: typeForm,
        idEmployee: this.idEmployee,
        idActivity: idActivity
      }
    }).afterClosed().subscribe((result) => {
      if (result) {
        this.getScheduleActivitiesByEmployee();
      }
    })
  }

  public setValueCell(activityEmployee: ActivityEmployee, indexColumn: number, indexRow: number) {
    let activity: string = '';
    if (indexColumn === 0) {
      activity = `#${activityEmployee.ID_ACTIVIDAD}`;
      return activity;
    }
    if (indexColumn === 1) {
      activity = `${activityEmployee.ACTIVIDAD}`;
      return activity;
    }
    if (indexColumn === 2) {
      activity = `${ this.resourcesService.formatOnlyDate(activityEmployee.FECHA_INICIO)} ${activityEmployee.HORA_INICIO}`;
      return activity;
    }
    if (indexColumn === 3) {
      if (activityEmployee.TIPO_ACTIVIDAD === 'NA' && activityEmployee.PERIODICIDAD !== null) {
        switch(activityEmployee.PERIODICIDAD) {
          case 'NR':
            activity = `No se repite`;
          break;
          case 'SE':
            activity = `Semanalmente`;
          break;
          case 'ME':
            activity = `Mensualmente`;
          break;
          case 'AN':
            activity = `Anualmente`;
          break;
          case 'TD':
            activity = `Todos los días`;
          break;
          case 'PE':
            activity = `Personalizado`;
          break;
        }
      } else if (activityEmployee.TIPO_ACTIVIDAD === 'MC' && activityEmployee.ID_ORDEN_CORRECTIVO != null){
        activity = `Orden #${activityEmployee.ID_ORDEN_CORRECTIVO} de MC`
      } else if (activityEmployee.TIPO_ACTIVIDAD === 'MP' && activityEmployee.ID_ORDEN_PREVENTIVO != null){
        activity = `Orden #${activityEmployee.ID_ORDEN_PREVENTIVO} de MP`

      };
      return activity;
    }
    if (indexColumn === 4) {
      activity = `${ activityEmployee.CLASIFICACION }`;
      return activity;
    }
    if (indexColumn === 5) {
      return activity;
    }

    return activity;
  }

  public alert(typeAlert: 'ELI', activityEmployee: ActivityEmployee) {
    if (typeAlert === 'ELI' && activityEmployee.ID_ACTIVIDAD !== undefined && activityEmployee.ID_ACTIVIDAD !== null) {
      this._dialog.open(AlertComponent, {
        disableClose: true,
        data: {
          title: `Eliminar Actividad`,
          description: `¿Está seguro de eliminar la actividad #${activityEmployee.ID_ACTIVIDAD}?`,
          icon: `warning`
        }
      }).afterClosed().subscribe(async (result) => {
        if (result && activityEmployee.ID_ACTIVIDAD !== undefined && activityEmployee.ID_ACTIVIDAD !== null) {
          await this.deleteActivity(activityEmployee.ID_ACTIVIDAD);
        }
      })
    }
  }

  private async deleteActivity(idActivity: string) {
    const encActivity: string = await this._encService.encrypt(idActivity.toString());
    const requestDeleteActivity: DeleteFormActivity = {
      USUARIO: this.resourcesService.getUser(),
      NUMERO_LINEA: this.resourcesService.getLineNumber()
    }
    await lastValueFrom(this._employeeService.deleteActivity(requestDeleteActivity, encActivity)).then(
      (responseData: ResponseData) => {
        if ( !responseData.error ) {
          this.resourcesService.openSnackBar(`¡Eliminación Exitosa!`);
          this.getScheduleActivitiesByEmployee();
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.deleteActivity(idActivity);
        }
      }
    );
  }
}
