import { SelectionModel } from '@angular/cdk/collections';
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { FormGroup, FormControl } from '@angular/forms';
import { ExportExcelService } from 'src/app/services/excel/export-excel.service';
import { MESMREService } from 'src/app/services/mes/mesmre/mesmre.service';
import { MESMREInterface } from 'src/app/interfaces/mes/mesmre/mesmre-interface';
import { MESMPRService } from 'src/app/services/mes/mesmpr/mesmpr.service';
import { MesmprInterface } from 'src/app/interfaces/mes/mesmpr/mesmpr-interface';
import { ENCService } from 'src/app/services/enc/enc.service';
import { IAMService } from 'src/app/services/iam/iam.service';
import { USERInterface } from 'src/app/interfaces/user-interface';

@Component({
  selector: 'app-mesmre',
  templateUrl: './mesmre.component.html',
  styleUrls: ['./mesmre.component.css'],
})
export class MESMREComponent implements AfterViewInit {

  isLoading: Boolean = true;
  isReloading: Boolean = false;
  isFilter: Boolean = false;
  isFilterNull: Boolean = true;
  isUser: Boolean = false;
  role = '';

  fecha_inicio = '';
  fecha_fin = '';

  //DATES
  options: any = {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  };
  
  rango = new FormGroup({
    fecha_inicio: new FormControl(),
    fecha_fin: new FormControl(),
  });

  //Historial
  solicitudes: MESMREInterface[] = [];

  //Todos
  solicitudes_todos: MESMREInterface[] = [];
  empleados: MESMREInterface[] = [];
  empleado:MESMREInterface = {} as MESMREInterface;

  //Periodos
  periodos:MesmprInterface[] = []

  nombre_usuario:string = "";

  opcionesSolicitudes  = [
    { valor: 0, tipo: 'Mi historial' },
    { valor: 1, tipo: 'Todos' }
  ];

  opcionSolicitud = this.opcionesSolicitudes[0].valor;
  tipoSolicitud = this.opcionesSolicitudes[0].tipo;

  opcionesEstatus = [
    {estatus: 'Aprobadas'},
    {estatus: 'Rechazadas'},
    {estatus: 'Pendientes'},
    {estatus: 'Canceladas'}
  ];

  opcionEstatus = null;
  opcionPeriodo = null;

  displayedColumns: string[] = [
    'select',
    'numero_solicitud',
    'nombre_empleado',
    'fecha_inicio',
    'fecha_fin',
    'numero_dias',
    'estatus',
    'periodo_vacacional',
    'vacaciones_antes',
    'vacaciones_despues',
  ];

  dataSource = new MatTableDataSource<any>(this.solicitudes);
  selection = new SelectionModel<MESMREInterface>(true, []);

  @ViewChild(MatPaginator) paginator!: MatPaginator;

  constructor(
    public dialog: MatDialog,
    private _snackBar: MatSnackBar,
    private _iamService: IAMService,
    private __mesmreService: MESMREService,
    private __mesmprService: MESMPRService,
    public excel: ExportExcelService,
    private _encService: ENCService
  ) {

    let usuario:USERInterface = JSON.parse(localStorage.getItem('TIMUSERENC')!);
    this.nombre_usuario = usuario.NOMBRE

    if (this._encService.desencriptar(JSON.parse(localStorage.getItem('TIMUSERENC')!).PERFIL) == 'Administrador') {
      this.role = 'Administrador'

    } else if (this._encService.desencriptar(JSON.parse(localStorage.getItem('TIMUSERENC')!).PERFIL) == 'Usuario') {
      this.opcionesSolicitudes = this.opcionesSolicitudes.slice(0, 1);
      this.isUser = true;
      this.role = 'Usuario'
    }

  }

  ngAfterViewInit(): void {
    this.obtener();
    this.obtenerEmpleados();
    this.obtenerPeriodos(this._encService.desencriptar(this.__mesmreService.usuario_session.IDUSUARIO));
  }

  obtener() {
    this.__mesmreService.consultar().subscribe((res:any) => {
      if (res.status == 'Token is Expired') {
        this._iamService.logout();
        this.snackAlert('Sesión expirada. Vuelva a iniciar sesión');
      }else if (!res.status) {
        this.solicitudes = res.response;
        this.cargarTabla(this.solicitudes);
        this.filtroEstatus();
      }else{
        this.snackAlert( res.response.length > 0 ? res.msg : 'No hay datos para mostrar');
      }
      this.isLoading = false;

    }, error => {
      if (!error.ok) {
        this.snackAlert('Ocurrió un error inesperado');
      }
      if (error.error.msg != undefined) {
        this.snackAlert(error.error.msg);
      }
      if (error.status == 408) {
        this.snackAlert('Conexion lenta');
      }
    });
  }

  obtenerEmpleados() {
    if (this._encService.desencriptar(JSON.parse(localStorage.getItem('TIMUSERENC')!).PERFIL) == 'Administrador') {
      this.__mesmreService.consultarTodos().subscribe((res:any) => {
        if (res.error) {
          this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
        } else {
          this.empleados = res.response;
          this.empleados = [...new Map(this.empleados.map(empleado => [empleado.NOMBREEMPLEADO, empleado])).values()]
          this.empleados = this.empleados.filter(solicitud => !solicitud.NOMBREEMPLEADO.includes(this._encService.desencriptar(this.__mesmreService.usuario_session.IDUSUARIO)))
        }
      }, (error:any) => {
        if (!error.ok) {
          this.snackAlert('Ocurrió un error inesperado');
        }
        if (error.error.msg != undefined) {

          this.snackAlert(error.error.msg);
        }
        if (error.status == 408) {
          this.snackAlert('Conexion lenta');
        }
      });
    } else if (this._encService.desencriptar(JSON.parse(localStorage.getItem('TIMUSERENC')!).PERFIL) == 'Usuario') {
      this.__mesmreService.consultarEmpleados().subscribe((res:any) => {
        if (res.error) {
          this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
        } else {
          this.empleados = res.response;
          this.empleados = [...new Map(this.empleados.map(empleado => [empleado.NOMBREEMPLEADO, empleado])).values()]
        }
      }, (error:any) => {
        if (!error.ok) {
          this.snackAlert('Ocurrió un error inesperado');
        }
        if (error.error.msg != undefined) {
          this.snackAlert(error.error.msg);
        }
        if (error.status == 408) {
          this.snackAlert('Conexion lenta');
        }
      });
    }
  }

  obtenerPeriodos(usuario:any) {
    this.__mesmprService.obtenerPeriodos(usuario).subscribe((res:any) => {
      if (res.status == 'Token is Expired') {
        this._iamService.logout();
        this.snackAlert('Sesión expirada. Vuelva a iniciar sesión');
      }else if (!res.status && res.response.length > 0) {        
        this.periodos = res.response;
      }else{
        if (res.msg !== "EXITO") {
          this.snackAlert(res.msg);
        }
      }
      this.isLoading = false;

    }, error => {
      if (!error.ok) {
        this.snackAlert('Ocurrió un error inesperado');
      }
      if (error.error.msg != undefined) {
        this.snackAlert(error.error.msg);
      }
      if (error.status == 408) {
        this.snackAlert('Conexion lenta');
      }
    });
  }

  filtroSolicitudes(filtro: string) {
    if (!this.isUser) {
      this.isReloading = true;
      this.tipoSolicitud = filtro;
      this.eliminarFiltros();
      switch (filtro) {
        case 'Mi historial':
          this.__mesmreService.consultar().subscribe((res:any) => {
            if (res.error) {
              this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
            } else {
              this.cargarTablaConSelects(res.response)
              this.mapearTabla();
              this.filtroEstatus();
              this.obtenerPeriodos(this._encService.desencriptar(this.__mesmreService.usuario_session.IDUSUARIO));
            }
          }, error => {
            if (!error.ok) {
              this.snackAlert('Ocurrió un error inesperado');
            }
            if (error.error.msg != undefined) {
              this.snackAlert(error.error.msg);
            }
            if (error.status == 408) {
              this.snackAlert('Conexion lenta');
            }
          });
          break;
        case 'Todos':
          this.__mesmreService.consultarTodos().subscribe((res:any) => {
            if (res.error) {
              this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
            } else {
              this.cargarTablaConSelects(res.response)
              this.mapearTabla();
              this.filtroEstatus();
              //Falta obtener todos los periodos
            }
          });
          break;
        default:
          this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
          this.isReloading = false;
          break;
      }
    }
  }

  filtroEmpleados(empleado:MESMREInterface) {
    //Se hace un split al primer parentesis, se obtiene la segunda posicion y se elimna el segundo parentesis
    if (empleado.NOMBREEMPLEADO.includes('(') && empleado.NOMBREEMPLEADO.includes(')')) {
      let usuario = empleado.NOMBREEMPLEADO.split('(')[1].replace(')','');
      this.eliminarFiltros();
      this.__mesmreService.consultarUsuario(usuario).subscribe((res:any) => {
        if (res.error) {
          this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
        } else {
          this.tipoSolicitud = usuario;
          this.cargarTablaConSelects(res.response)
          this.mapearTabla();
          this.filtroEstatus();
          this.obtenerPeriodos(usuario);
        }
      }, error => {        
        if (!error.ok) {
          this.snackAlert('Ocurrió un error inesperado');
        }
        if (error.error.msg != undefined) {
          this.snackAlert(error.error.msg);
        }
        if (error.status == 408) {
          this.snackAlert('Conexion lenta');
        }
      });
    } else {
      //No cargo los datos del id
      this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
    }
  }

  filtroEstatus() {
    let filtro_estatus = [...new Map(this.solicitudes.map(solicitud => [solicitud.ESTATUS, solicitud])).values()]
    this.opcionesEstatus = [];
    filtro_estatus.forEach(estatus => {
      this.opcionesEstatus.push({'estatus': estatus.ESTATUS})
    });
  }

  filtrosBusqueda() {
    if (this.solicitudes.length > 0) {
      let filtro_solicitudes: MESMREInterface[] = [];
      this.isFilter = true;
      //El filtro aplica a los rangos ?
      if (this.rango.value.fecha_inicio != null && this.rango.value.fecha_fin != null) {
        //Obtengo el tiempo transcurrido
        let rango_fecha_inicio = new Date(this.rango.value.fecha_inicio).getTime();
        let rango_fecha_fin = new Date(this.rango.value.fecha_fin).getTime();
        
        //Las 2 fechas del rango son menores a la fecha inicio ? true
        //Las 2 fechas del rango son mayores a la fecha fin ? true
        //Si las fechas del rango no son menores ni mayores entonces son *false* las condiciones,
        //Se debe de enviar verdadero si no excede este rango !false

        /*console.log(!(rango_fecha_inicio < Date.parse(this.solicitudes[0].FECHAINICIO.split('-0').join('-')) 
        && rango_fecha_fin < Date.parse(this.solicitudes[0].FECHAINICIO.split('-0').join('-'))) 
        && !(rango_fecha_inicio > Date.parse(this.solicitudes[0].FECHAFIN.split('-0').join('-')) 
        && rango_fecha_fin > Date.parse(this.solicitudes[0].FECHAFIN.split('-0').join('-'))));*/

        filtro_solicitudes = this.solicitudes.filter(
        solicitud => !(rango_fecha_inicio < Date.parse(solicitud.FECHAINICIO.split('-0').join('-')) 
        && rango_fecha_fin < Date.parse(solicitud.FECHAINICIO.split('-0').join('-'))) 
        && !(rango_fecha_inicio > Date.parse(solicitud.FECHAFIN.split('-0').join('-')) 
        && rango_fecha_fin > Date.parse(solicitud.FECHAFIN.split('-0').join('-'))))
      }

      //FILTROS

      //TODOS LOS FILTROS FUERON SOLICITADOS
      if (this.rango.value.fecha_inicio != null && this.rango.value.fecha_fin != null && this.opcionEstatus != null && this.opcionPeriodo != null) {
        filtro_solicitudes = filtro_solicitudes.filter(solicitud => solicitud.ESTATUS == this.opcionEstatus && solicitud.PERIODOVACACIONAL == this.opcionPeriodo);
      //RANGO FECHAS Y ESTATUS
      }else if (this.rango.value.fecha_inicio != null && this.rango.value.fecha_fin != null && this.opcionEstatus != null) {
        filtro_solicitudes = filtro_solicitudes.filter(solicitud => solicitud.ESTATUS == this.opcionEstatus);
      //RANGO FECHAS Y PERIODO
      }else if (this.rango.value.fecha_inicio != null && this.rango.value.fecha_fin != null && this.opcionPeriodo != null) {
        filtro_solicitudes = filtro_solicitudes.filter(solicitud => solicitud.ESTATUS == this.opcionEstatus);
      //ESTATUS Y PERIODO
      }else if (this.opcionEstatus != null && this.opcionPeriodo != null) {
      filtro_solicitudes = this.solicitudes.filter(solicitud => solicitud.ESTATUS == this.opcionEstatus && solicitud.PERIODOVACACIONAL == this.opcionPeriodo);
      //ESTATUS
      }else if (this.opcionEstatus != null) {
        filtro_solicitudes = this.solicitudes.filter(solicitud => solicitud.ESTATUS == this.opcionEstatus);
      //PERIODO
      }else if (this.opcionPeriodo != null) {
        filtro_solicitudes = this.solicitudes.filter(solicitud => solicitud.PERIODOVACACIONAL == this.opcionPeriodo);
      }
      
      this.dataSource.data = filtro_solicitudes;
      this.selection = new SelectionModel<MESMREInterface>(
        true,
        filtro_solicitudes
      );
      this.isReloading = false;
    }
  }

  eliminarFiltros() {    
    this.isFilter = false
    this.isFilterNull = true;
    if (this.rango.value.fecha_inicio != null || this.rango.value.fecha_fin != null || this.opcionesEstatus != null || this.opcionPeriodo != null) {

      if (this.rango.value.fecha_inicio != null || this.rango.value.fecha_fin != null) {
        this.rango = new FormGroup({
          fecha_inicio: new FormControl(),
          fecha_fin: new FormControl(),
        });
      }
      if (this.opcionEstatus != null) {
        this.opcionEstatus = null;
      }
      if (this.opcionPeriodo != null) {
        this.opcionPeriodo = null;
      }
      switch (this.opcionSolicitud) {
        case 0:
          this.__mesmreService.consultar().subscribe((res:any) => {
            if (res.error) {
              this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
            } else {
              this.cargarTablaConSelects(res.response)
              this.mapearTabla();
            }
          }, error => {
            if (!error.ok) {
              this.snackAlert('Ocurrió un error inesperado');
            }
            if (error.error.msg != undefined) {
              this.snackAlert(error.error.msg);
            }
            if (error.status == 408) {
              this.snackAlert('Conexion lenta');
            }
          });
          break;
        case 1:
          this.__mesmreService.consultarTodos().subscribe((res:any) => {
            if (res.error) {
              this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
            } else {
              this.cargarTablaConSelects(res.response)
              this.mapearTabla();
              //Falta obtener todos los periodos
            }
          }, (error:any) => {
            if (!error.ok) {
              this.snackAlert('Ocurrió un error inesperado');
            }
            if (error.error.msg != undefined) {
              this.snackAlert(error.error.msg);
            }
            if (error.status == 408) {
              this.snackAlert('Conexion lenta');
            }
          });
          break;
        case 2:
          this.__mesmreService.consultarUsuario(this.tipoSolicitud).subscribe((res:any) => {
            if (res.error) {
              this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
            } else {
              this.cargarTablaConSelects(res.response)
              this.mapearTabla();
            }
          }, error => {
            if (!error.ok) {
              this.snackAlert('Ocurrió un error inesperado');
            }
            if (error.error.msg != undefined) {
              this.snackAlert(error.error.msg);
            }
            if (error.status == 408) {
              this.snackAlert('Conexion lenta');
            }
          });
          break;
        default:
          this.snackAlert('Ocurrió un error inesperado, favor de intentarlo más tarde');
          break;
      }
    }
  }

  validarOpcionesFiltro() {
    //Saber si los filtros estan nulos
    if (this.rango.value.fecha_inicio != null && this.rango.value.fecha_fin != null || this.opcionEstatus != null || this.opcionPeriodo != null) {
      this.isFilterNull = false;
    } else {
      this.isFilterNull = true;
    }
  }

  cargarTablaConSelects(solicitudes:MESMREInterface[]) {
    this.solicitudes = solicitudes;
    this.dataSource.data = this.solicitudes;
    this.selection = new SelectionModel<MESMREInterface>(
      true,
      solicitudes
    );
    this.isReloading = false;
  }

  mapearTabla() {
    this.solicitudes.map(function (
      solicitud: MESMREInterface
    ) {      
      if (solicitud.PERIODOVACACIONAL == null) {
        solicitud.PERIODOVACACIONAL = 'N/A';
      }
      if (solicitud.VACACIONESANTES == null) {
        solicitud.VACACIONESANTES = 0;
      }
      if (solicitud.VACACIONESDESPUES == null) {
        solicitud.VACACIONESDESPUES = 0;
      }
      return {
        IDSOLICITUD: solicitud.IDSOLICITUD,
        NOMBREEMPLEADO: solicitud.NOMBREEMPLEADO,
        FECHAINICIO: solicitud.FECHAINICIO,
        FECHAFIN: solicitud.FECHAFIN,
        NUMERODIAS: solicitud.NUMERODIAS,
        ESTATUS: solicitud.ESTATUS,
        PERIODOVACACIONAL: solicitud.PERIODOVACACIONAL,
        VACACIONESANTES: solicitud.VACACIONESANTES,
        VACACIONESDESPUES: solicitud.VACACIONESDESPUES
      };
    });
  }

  cargarTabla(solicitudes:MESMREInterface[]) {
    this.isLoading = false;
    this.solicitudes = solicitudes;
    this.dataSource = new MatTableDataSource<MESMREInterface>(this.solicitudes);
    this.selection = new SelectionModel<MESMREInterface>(
      true,
      solicitudes
    );

    this.dataSource.filterPredicate = function (
      data: MESMREInterface,
      filter: string
    ): boolean {
      return (
        data.IDSOLICITUD.toString().toLowerCase().includes(filter) ||
        data.NOMBREEMPLEADO.toLowerCase().includes(filter) ||
        data.FECHAINICIO.toString().toLowerCase().includes(filter) ||
        data.FECHAFIN.toString().toLowerCase().includes(filter) ||
        data.NUMERODIAS.toString().toLowerCase().includes(filter) ||
        data.ESTATUS.toLowerCase().includes(filter) ||
        data.PERIODOVACACIONAL.toString().toLowerCase().includes(filter) ||
        data.VACACIONESANTES.toString().toLowerCase().includes(filter) ||
        data.VACACIONESDESPUES.toString().toLowerCase().includes(filter)
      );
    };

    this.dataSource.paginator = this.paginator;
    this.paginator._intl.itemsPerPageLabel = 'Datos por página';
    this.paginator._intl.firstPageLabel = 'Primera Página';
    this.paginator._intl.lastPageLabel = 'Últmina Página';
    this.paginator._intl.nextPageLabel = 'Siguiente Página';
    this.paginator._intl.previousPageLabel = 'Anterior Página';

    this.mapearTabla();
  }

  formatoFecha(fecha:string): string {
    let split = fecha.split('-');
    return `${split[2]}-${split[1]}-${split[0]}`
  }

  applyFilter(filterValue: any) {
    this.dataSource.filter = filterValue.target.value.trim().toLowerCase();
  }

  isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
  }

  masterToggle() {
    if (this.isAllSelected()) {
      this.selection.clear();
      return;
    }

    this.selection.select(...this.dataSource.data);
  }

  checkboxLabel(row?: MESMREInterface): string {
    if (!row) {
      return `${this.isAllSelected() ? 'deselect' : 'select'} all`;
    }
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row`;
  }

  generarExcel(): void {
    if (this.selection.selected.length > 0) {
      //let hoy = new Date(2022,1,1,1,1,1);    
      let hoy = new Date();    
      let anio = hoy.getFullYear();
      let mes = hoy.getMonth() + 1;
      let dia = hoy.getDate();
      let hora = hoy.getHours();
      let minuto = hoy.getMinutes();
      let segundos = hoy.getSeconds();

      let titulo = this.tipoSolicitud
      let filename = 'reporte_'+this.tipoSolicitud.toLowerCase()+'_'+ anio + (mes < 10 ? '0': '')+ mes 
        + (dia < 10 ? '0': '') + dia + '_' + (hora < 10 ? '0': '') + hora 
        + (minuto < 10 ? '0': '') + minuto + (segundos < 10 ? '0': '') + segundos;
      
      this.excel.generarExcel(this.selection.selected, filename, titulo)
    } else {
      this.snackAlert('Para generar el Excel se debe seleccionar al menos una fila');
    }
  }

  formatDate(fecha:string){
    let arrFecha = fecha.split("-");
    return `${arrFecha[2]}-${arrFecha[1]}-${arrFecha[0]}`;
  }

  private snackAlert(mensaje: string) {
    this._snackBar.open(mensaje, 'Cerrar', {
      duration: 4000,
    });
  }
}
