import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import {
  MAT_MOMENT_DATE_FORMATS,
  MomentDateAdapter,
  MAT_MOMENT_DATE_ADAPTER_OPTIONS,
} from '@angular/material-moment-adapter';
import {
  DateAdapter,
  MAT_DATE_FORMATS,
  MAT_DATE_LOCALE,
} from '@angular/material/core';
import {
  MatCalendarCellClassFunction,
  MatDatepickerInputEvent,
} from '@angular/material/datepicker';

import { MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import * as moment from 'moment';
import { AlertaComponent } from 'src/app/components/resources/dialogos/alerta/alerta.component';
import { USERInterface } from 'src/app/interfaces/user-interface';
import { ENCService } from 'src/app/services/enc/enc.service';
import { MCOMDFService } from 'src/app/services/mco/mcomdf/mcomdf.service';
import { MCOMPVService } from 'src/app/services/mco/mcompv/mcompv.service';
import { MESMSVService } from 'src/app/services/mes/mesmsv/mesmsv.service';
import { ValidationsService } from 'src/app/services/validations.service';

@Component({
  selector: 'app-mesmhs-form-days',
  templateUrl: './mesmhs-form-days.component.html',
  styleUrls: ['./mesmhs-form-days.component.css'],
  providers: [
    { provide: MAT_DATE_LOCALE, useValue: 'es-MX ' },
    {
      provide: DateAdapter,
      useClass: MomentDateAdapter,
      deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS],
    },
    { provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },
  ],
  encapsulation: ViewEncapsulation.None,
})
export class MESMHSFORMDAYSComponent implements OnInit {
  formGroup: FormGroup;
  dias: number = 0;
  dias_feriados: any[] = null!;
  politica: string = null!;

  usuario_session: USERInterface = JSON.parse(
    localStorage.getItem('TIMUSERENC')!
  );

  array_disables: any[] = [];
  dates_disable: any = [];
  days_week_disable: any = [];

  constructor(
    private _encService: ENCService,
    public dialog: MatDialog,
    private _mcomdfService: MCOMDFService,
    private _mcompvService: MCOMPVService,
    private _snackBar: MatSnackBar,
    private _mesmsv: MESMSVService,
    private _validationService: ValidationsService,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) {
    this.formGroup = this.createFormGroup();
  }

  ngOnInit(): void {
    this.obtenerDiasFeriados();
  }

  dateClass: MatCalendarCellClassFunction<Date> = (cellDate, view) => {
    let dateToString = cellDate?.toString();
    cellDate = new Date(dateToString!);

    if (view === 'month') {
      return this.filterDays(cellDate);
    }
    return '';
  };

  async filterDays(cellDate: any) {
    const sleep = (ms: number) =>
      new Promise((resolve) => setTimeout(resolve, ms));
    const collection = document.getElementsByClassName(
      'mat-calendar-body-cell-content'
    ) as HTMLCollectionOf<HTMLElement>;

    await sleep(100);

    let dateToString = cellDate?.toString();
    let lastPosition = this.dates_disable[this.dates_disable.length - 1];
    cellDate = new Date(dateToString!);

    for (let index = 0; index < this.dates_disable.length; index++) {
      if (
        cellDate.getDate() == this.dates_disable[index].getDate() &&
        cellDate.getMonth() == this.dates_disable[index].getMonth() &&
        cellDate.getFullYear() == lastPosition.getFullYear()
      ) {
        collection[cellDate.getDate() - 1].style.color = 'white';
        collection[cellDate.getDate() - 1].style.background = 'orange';

        return 'example-custom-date-class';
      }

      if (
        cellDate.getDay() == this.days_week_disable[0] ||
        cellDate.getDay() == this.days_week_disable[1] ||
        cellDate.getDay() == this.days_week_disable[2] ||
        cellDate.getDay() == this.days_week_disable[3] ||
        cellDate.getDay() == this.days_week_disable[4] ||
        cellDate.getDay() == this.days_week_disable[5] ||
        cellDate.getDay() == this.days_week_disable[6]
      ) {
        if (cellDate.getFullYear() == lastPosition.getFullYear()) {
          collection[cellDate.getDate() - 1].style.color = '#0288d1';

          collection[cellDate.getDate() - 1].style.fontWeight = 'bold';

          return 'weekendsDays';
        }
      }
    }

    return '';
  }

  private createFormGroup() {
    
    let fechaInicio2 = new Date(this.dateFormat(this.data.item.FECHAFINAL));
    fechaInicio2 = new Date(fechaInicio2.getFullYear(), fechaInicio2.getMonth(), fechaInicio2.getDate() + 2);
    let str_fecha_inicio = fechaInicio2.toISOString().split('T')[0]
    
    return new FormGroup({
      numero_empleado: new FormControl({
        value: this.data.item.IDUSUARIO,
        disabled: true,
      }),
      dias_anteriores: new FormControl({
        value: this.data.item.NUMERODIAS,
        disabled: true,
      }),
      fecha_inicio: new FormControl(
        {
          value: this.momentDate(this.dateFormat(this.data.item.FECHAINICIAL)),
          disabled: false,
        },
        Validators.required
      ),
      fecha_final: new FormControl(
        {
          value: this.momentDate(this.dateFormat(this.data.item.FECHAFINAL)),
          disabled: false,
        },
        Validators.required
      ),
      fecha_inicio_2: new FormControl(
        {
          value: this.momentDate(str_fecha_inicio),
          disabled: true,
        },
        Validators.required
      ),
      fecha_minima: new FormControl(
        {
          value: this.momentDate(
            this.dateFormat(this.data.item.FECHAFINAL)
          ).add(1, 'day'),
          disabled: false,
        },
        Validators.required
      ),
      fecha_final_2: new FormControl(
        {
          value: '',
          disabled: false,
        },
        Validators.required
      ),
      dias_vacacionales: new FormControl({ value: '', disabled: false }),
    });
  }

  updateRequest() {
    let days_auxiliar =
      this.dias_vacacionales?.value - this.data.item.NUMERODIAS;

    let solicitud = {
      id_solicitud: this.data.item.IDSOLICITUD,
      fecha_final: this.formatDate(this.fecha_final_2?.value),
      extra_dias: this.dias_vacacionales?.value,
      numero_empleado_modifica: this._encService.desencriptar(this.usuario_session.IDUSUARIO),
      rfc_empresa: this.usuario_session.RFCEMPRESA,
    };

    this._mesmsv.modificar(solicitud).subscribe(
      (data: any) => {
        if (!data.error) {
          this._validationService.openSnackBar(
            '¡Los días vacacionales fueron agregados con éxito!'
          );
        } else {
          this._validationService.openSnackBar(data.msg);
        }
      },
      (error: any) => {
        if (!error.ok) {
          this._validationService.openSnackBar('Ocurrió un error inesperado');
        }
        if (error.error.msg != undefined) {
          this._validationService.openSnackBar(error.error.msg);
        }
        if (error.status == 408) {
          this._validationService.openSnackBar('Conexion lenta');
        }
      }
    );
  }

  openDialog() {
    let dataAction = {
      titulo: 'Confirmación',
      descripcion:
        '¿Está seguro de agregar los nuevos días vacacionales a la solicitud?',
    };

    const dialogRef = this.dialog.open(AlertaComponent, {
      data: dataAction,
    });

    dialogRef.afterClosed().subscribe((result) => {
      if (result) {
        this.updateRequest();
        this.dialog.closeAll();
      }
    });
  }

  calcular_dias() {
    let dias_semana: any = [];

    if (this.politica != null) {
      dias_semana = Object.values(JSON.parse(this.politica));
    }

    let cont = 0;
    if (this.fecha_final_2?.value != null) {
      if (
        (this.fecha_inicio?.value._d != undefined &&
          this.fecha_final_2?.value._d != undefined) ||
        (this.fecha_inicio?.value._d != null &&
          this.fecha_final_2?.value._d != null)
      ) {

        let fecha1: Date = this.fecha_inicio_2?.value ;
        let fecha2: Date = this.fecha_final_2?.value._d;     

        

        this.dias = this.difference(fecha1, fecha2) + 1;

        for (let index = 0; index < this.dias; index++) {
          let dia_semana_recorrida = fecha1.getDay();

          if (dias_semana[0] != 'Si' && dia_semana_recorrida == 0) {
            cont++;
          }

          if (dias_semana[1] != 'Si' && dia_semana_recorrida == 4) {
            cont++;
          }

          if (dias_semana[2] != 'Si' && dia_semana_recorrida == 1) {
            cont++;
          }

          if (dias_semana[3] != 'Si' && dia_semana_recorrida == 2) {
            cont++;
          }

          if (dias_semana[4] != 'Si' && dia_semana_recorrida == 3) {
            cont++;
          }

          if (dias_semana[5] != 'Si' && dia_semana_recorrida == 6) {
            cont++;
          }

          if (dias_semana[6] != 'Si' && dia_semana_recorrida == 5) {
            cont++;
          }

          if (dia_semana_recorrida) {
          }

          this.dias_feriados.forEach((element) => {
            if (
              element.DIA == fecha1.getDate() &&
              element.MES - 1 == fecha1.getMonth()
            ) {
              if (dia_semana_recorrida == 6 || dia_semana_recorrida == 0) {
              } else {
                cont--;
              }
            }
          });

          fecha1 = new Date(
            fecha1.getFullYear(),
            fecha1.getMonth(),
            fecha1.getDate() + 1
          );
        }
        this.dias_vacacionales?.setValue(cont);

        return cont;
      }
      return 0;
    }
    return 0;
  }
  
  applyFilter(e: any) {
    let dias_semana = Object.values(JSON.parse(this.politica));
    let diasVacaciones = parseInt(e.target.value);
    let cont = 0;
    let diasFeriados = 0;
    let fecha1 = this.fecha_inicio_2?.value._d === undefined ? this.fecha_inicio_2?.value : this.fecha_inicio_2?.value._d;
    do {
      this.dias_feriados.forEach((element) => {
        if (
          element.DIA == fecha1.getDate() &&
          element.MES - 1 == fecha1.getMonth()
        ) {
          if (dias_semana[0] != 'Si' && fecha1.getDay() == 0) {
            diasFeriados++;
          }

          if (dias_semana[1] != 'Si' && fecha1.getDay() == 4) {
            diasFeriados++;
          }

          if (dias_semana[2] != 'Si' && fecha1.getDay() == 1) {
            diasFeriados++;
          }

          if (dias_semana[3] != 'Si' && fecha1.getDay() == 2) {
            diasFeriados++;
          }

          if (dias_semana[4] != 'Si' && fecha1.getDay() == 3) {
            diasFeriados++;
          }

          if (dias_semana[5] != 'Si' && fecha1.getDay() == 6) {
            diasFeriados++;
          }

          if (dias_semana[6] != 'Si' && fecha1.getDay() == 5) {
            diasFeriados++;
          }
        }
      });

      if (dias_semana[0] == 'Si' && fecha1.getDay() == 0) {
        diasFeriados++;
      }

      if (dias_semana[1] == 'Si' && fecha1.getDay() == 4) {
        diasFeriados++;
      }

      if (dias_semana[2] == 'Si' && fecha1.getDay() == 1) {
        diasFeriados++;
      }

      if (dias_semana[3] == 'Si' && fecha1.getDay() == 2) {
        diasFeriados++;
      }

      if (dias_semana[4] == 'Si' && fecha1.getDay() == 3) {
        diasFeriados++;
      }

      if (dias_semana[5] == 'Si' && fecha1.getDay() == 6) {
        diasFeriados++;
      }

      if (dias_semana[6] == 'Si' && fecha1.getDay() == 5) {
        diasFeriados++;
      }

      if (cont + 1 == diasVacaciones) {
        fecha1 = new Date(
          fecha1.getFullYear(),
          fecha1.getMonth(),
          fecha1.getDate() + diasFeriados
        );
      } else {
        if (diasFeriados > 0) {
          fecha1 = new Date(
            fecha1.getFullYear(),
            fecha1.getMonth(),
            fecha1.getDate() + diasFeriados
          );
        } else {
          fecha1 = new Date(
            fecha1.getFullYear(),
            fecha1.getMonth(),
            fecha1.getDate() + 1
          );
        }
      }

      if (diasFeriados == 0) {
        cont++;
      }

      diasFeriados = 0;
    } while (cont < diasVacaciones);

    this.fecha_final_2?.setValue(fecha1);
  }

  changeNewDate(event: MatDatepickerInputEvent<Date>) {
    if (event.value !== null) {
      let fechafinal = this.data.item.FECHAFINAL.split("-");
      let fechaInicio2 = new Date(fechafinal[2], fechafinal[1] - 1, fechafinal[0]);
      //fechaInicio2 = new Date(fechaInicio2.getFullYear(), fechaInicio2.getMonth(), fechaInicio2.getDate());
      fechaInicio2.setDate(fechaInicio2.getDate() + 1);
      let str_fecha_inicio = `${fechaInicio2.getDate()}-${fechaInicio2.getMonth()}-${fechaInicio2.getFullYear()}`

      console.log(str_fecha_inicio);
      console.log( this.getDateWithString(str_fecha_inicio));
      console.log(this.getDateWithString(this.dateFormatInvert(str_fecha_inicio)));
      
      
      if (
        new Date(event.value).getTime() >= fechaInicio2.getTime()
      ) {
        this.formGroup.patchValue({
          fecha_inicio_2: fechaInicio2,
        });
        this.calcular_dias();
      } else {
        this.formGroup.patchValue({
          fecha_final_2: '',
        });
      }
    }
  }

  private formatDate(date: Date) {
    var d = new Date(date),
      month = '' + (d.getMonth() + 1),
      day = '' + d.getDate(),
      year = d.getFullYear();

    if (month.length < 2) month = '0' + month;
    if (day.length < 2) day = '0' + day;

    return [year, month, day].join('-');
  }

  private momentDate(fecha: string) {
    return moment(fecha);
  }

  private getDateWithString(fecha: string) {
    let fechaAux = fecha.split('-');

    return new Date(
      parseInt(fechaAux[2]),
      parseInt(fechaAux[1]) - 1,
      parseInt(fechaAux[0])
    );
  }

  private dateFormat(fecha: string) {
    let fechaAux = fecha.split('-');

    return `${fechaAux[2]}-${fechaAux[1]}-${fechaAux[0]}`;
  }

  private dateFormatInvert(fecha: string) {
    let fechaAux = fecha.split('-');

    return `${fechaAux[0]}-${fechaAux[1]}-${fechaAux[2]}`;
  }

  private addDayDate(fecha: Date) {
    fecha.setDate(fecha.getDate() + 1);

    return fecha;
  }

  private obtenerDiasFeriados() {
    this._mcomdfService.obtener().subscribe(
      (response) => {
        this.dias_feriados = response.response;
        this.dates_disable = response.response.map((object: any) => {
          return new Date(object.ANIO, object.MES - 1, object.DIA);
        });
      },
      (error) => {
        if (!error.ok) {
          this._validationService.openSnackBar('Ocurrió un error inesperado');
        }
        if (error.error.msg != undefined) {
          this._validationService.openSnackBar(error.error.msg);
        }
        if (error.status == 408) {
          this._validationService.openSnackBar('Conexion lenta');
        }
      }
    );

    this._mcompvService
      .obtenerPoliticaUsuario(this.data.item.IDPOLITICA)
      .subscribe(
        (response) => {
          this.politica = response.response.DIASDESCANSO;
          let convert = JSON.parse(response.response.DIASDESCANSO);
          this.getDaysPolitician(convert);
        },
        (error) => {
          if (!error.ok) {
            this._validationService.openSnackBar('Ocurrió un error inesperado');
          }
          if (error.error.msg != undefined) {
            this._validationService.openSnackBar(error.error.msg);
          }
          if (error.status == 408) {
            this._validationService.openSnackBar('Conexion lenta');
          }
        }
      );
  }

  getDaysPolitician(convert: any) {
    if (convert.Do == 'Si') {
      this.days_week_disable.push(0);
    }

    if (convert.Lu == 'Si') {
      this.days_week_disable.push(1);
    }

    if (convert.Ma == 'Si') {
      this.days_week_disable.push(2);
    }

    if (convert.Mi == 'Si') {
      this.days_week_disable.push(3);
    }

    if (convert.Ju == 'Si') {
      this.days_week_disable.push(4);
    }

    if (convert.Vi == 'Si') {
      this.days_week_disable.push(5);
    }

    if (convert.Sa == 'Si') {
      this.days_week_disable.push(6);
    }
  }

  get numero_empleado() {
    return this.formGroup.get('numero_empleado');
  }

  get fecha_inicio() {
    return this.formGroup.get('fecha_inicio');
  }

  get fecha_inicio_2() {
    return this.formGroup.get('fecha_inicio_2');
  }

  get fecha_final() {
    return this.formGroup.get('fecha_final');
  }

  get fecha_final_2() {
    return this.formGroup.get('fecha_final_2');
  }

  get fecha_minima() {
    return this.formGroup.get('fecha_minima');
  }

  get dias_vacacionales() {
    return this.formGroup.get('dias_vacacionales');
  }

  get dias_anteriores() {
    return this.formGroup.get('dias_anteriores');
  }

  private difference(date1: Date, date2: Date) {
    const date1utc = Date.UTC(
      date1.getFullYear(),
      date1.getMonth(),
      date1.getDate()
    );
    const date2utc = Date.UTC(
      date2.getFullYear(),
      date2.getMonth(),
      date2.getDate()
    );
    let day = 1000 * 60 * 60 * 24;
    return (date2utc - date1utc) / day;
  }
}
