import { OrderFiltersComponent } from './order-filters/order-filters.component';
import { MatSnackBar } from '@angular/material/snack-bar';
import { EndOrderComponent } from './end-order/end-order.component';
import { OrderViewerComponent } from './order-viewer/order-viewer.component';
import { MatDialog } from '@angular/material/dialog';
import { MatSort } from '@angular/material/sort';
import { MatPaginator } from '@angular/material/paginator';
import { FunctionsService } from './../../../services/functions.service';
import { StartedWorkOrder, StartedWorkOrdersResponse } from './../../../interfaces/started-work-orders.interface';
import { PreventiveMaintenanceService } from './../../../services/preventive-maintenance.service';
import { lastValueFrom } from 'rxjs';
import { EncService } from './../../../services/enc/enc.service';
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';

@Component({
  selector: 'app-work-orders-history',
  templateUrl: './work-orders-history.component.html',
  styleUrls: ['./work-orders-history.component.css']
})
export class WorkOrdersHistoryComponent implements OnInit {
  public btnSmall: boolean = false;
  public txtBuscador:string;

  isLoading: boolean;
  hasError: boolean;
  hasFilters: boolean;
  errorStr: string;
  
  dataSource?: MatTableDataSource<StartedWorkOrder>;
  displayedColumns = ['ID', 'TITULO', 'TIEMEST', 'PRIORIDAD', 'ESTADO', 'FECPRO', 'FECEJE', 'USUEJE', 'ACCIONES'];

  @ViewChild(MatPaginator) paginator?: MatPaginator;
  @ViewChild(MatSort) sort?: MatSort;

  workOrders: StartedWorkOrder[];

  constructor(
    private _encService: EncService,
    private _prevMaintService: PreventiveMaintenanceService,
    private _funcService: FunctionsService,
    private _dialog: MatDialog,
    private _snackBar: MatSnackBar,
  ) { 
    this.btnSmall = window.innerWidth <= 1405;
    this.txtBuscador = '';

    this.isLoading = true;
    this.hasError = false;
    this.hasFilters = false;
    this.errorStr = "";

    this.workOrders = [];
  }

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

  public onResize():void {
    this.btnSmall = window.innerWidth <= 1405;
  }

  applyFilter(event: any, type: string){
    let filterValue:string;
    if (type == 'INP') {
      filterValue = (event.target as HTMLInputElement).value;
    }else{
      this.txtBuscador = event;
      filterValue = event;
    }
    this.dataSource!.filter = filterValue.trim().toLowerCase();

    if(this.dataSource?.paginator){
      this.dataSource.paginator.firstPage();
    }
  }

  async getStartedWorkOrders(){
    try{
      this.isLoading = true;
      this.hasError = false;
      this.errorStr = "";

      let idUser = localStorage.getItem('idusuario')!;
      let startedWorkOrders: StartedWorkOrdersResponse = await lastValueFrom(this._prevMaintService.getStartedWorkOrders(idUser, 1));

      this.hasError = startedWorkOrders.error;
      this.errorStr = startedWorkOrders.msg;

      if(!this.hasError){
        this.workOrders = startedWorkOrders.response;
        this.dataSource = new MatTableDataSource(startedWorkOrders.response);
        this.dataSource.paginator = this.paginator!;
        this.dataSource.sort = this.sort!;
      }

      this.isLoading = false;
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió une error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió une error inesperado.';
      }else{
        this.errorStr = error.error.msg;
      }

      this.hasError = true;
      this.isLoading = false;
    }
  }

  getPriority(priority: string): string{
    if(priority == '1'){
      return "Alta";
    }else if(priority == '2'){
      return "Media";
    }else{
      return "Baja";
    }
  }

  orderProgDate(date: string, time: string): string{
    let dateTime = `${date} ${time}`;
    return this._funcService.orderDate(dateTime)!;
  }

  orderEjeDate(dateTime: string): string{
    return this._funcService.orderDate(dateTime)!;
  }

  openOrder(idOrder: number){
    this._dialog.open(OrderViewerComponent, {
      width: '480px',
      data: {
        idOrder: idOrder,
      }
    });
  }

  openEndOrder(idReg: number, idOrder: number){
    let dialogRef = this._dialog.open(EndOrderComponent, {
      width: '420px',
      disableClose: true,
      data: {
        idOrder: idOrder,
        idReg: idReg
      }
    })
    

    dialogRef.afterClosed().subscribe(res => {
      if(res !=  null && res != undefined && res != ""){
        this.endOrder(idReg, idOrder, res);
      }
    });
  }

  async endOrder(idReg: number, idOrder: number, obse: string){
    try{
      let idUser = localStorage.getItem('idusuario');
      let formData = new FormData();

      formData.append('id_user', idUser!);
      formData.append('linea', '1');
      formData.append('id_order', `${idOrder}`);
      formData.append('observations', `${obse}`);
      formData.append('id_reg', `${idReg}`);

      await lastValueFrom(this._prevMaintService.endOrderExecution(formData));

      this.openSnackBar('La orden se actualizó correctamente.');
      this.isLoading = true;
      this.hasError = false;
      this.errorStr = "";
      this.getStartedWorkOrders();
    }catch(error: any){
      if(error.error == undefined){
        this.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this.openSnackBar(error.error.msg);
      }
    }
  }

  openSnackBar(msg: string){
    this._snackBar.open(msg, undefined, {
      duration: 2500,
    })
  }

  openFilters(){
    let regUsers: Map<string, string> = new Map();
    this.workOrders.forEach(item => {
      let usrEjeArr = item.USUARIOEJECUCION.split('(').reverse();
      let idUser = usrEjeArr[0].replace(')', '');

      regUsers.set(idUser, item.USUARIOEJECUCION);
    });
    
    let dialogRef = this._dialog.open(OrderFiltersComponent, {
      width: '720px',
      data: {
        regUsers: regUsers,
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ""){
        let filters = JSON.parse(res);
        let numFilters = 0;

        let state = filters[0];
        let feprin = filters[1];
        let feprfi = filters[2];
        let feejin = filters[3];
        let feejfi = filters[4];
        let usrEje = filters[5];

        let arrAux = this.workOrders;
        if(state != null && state!= undefined && state != ""){
          arrAux = arrAux.filter(item => item.ESTADO == state);
          numFilters++;
        }

        if(this.validDate(feprin) && !this.validDate(feprfi)){
          arrAux = arrAux.filter(item => this.buildDateObject(item.FECHAPROGRAMA) >= this.buildDateObject(feprin));
          numFilters++;
        }else if(!this.validDate(feprin) && this.validDate(feprfi)){
          arrAux = arrAux.filter(item => this.buildDateObject(item.FECHAPROGRAMA) <= this.buildDateObject(feprfi));
          numFilters++;
        }else if(this.validDate(feprin) && this.validDate(feprfi)){
          arrAux = arrAux.filter(item => this.buildDateObject(item.FECHAPROGRAMA) >= this.buildDateObject(feprin) && this.buildDateObject(item.FECHAPROGRAMA) <= this.buildDateObject(feprfi));
          numFilters++;
        }

        if(this.validDate(feejin) && !this.validDate(feejfi)){
          arrAux = arrAux.filter(item => this.buildDateObject(item.FECHAEJECUCION) >= this.buildDateObject(feejin));
          numFilters++;
        }else if(!this.validDate(feejin) && this.validDate(feejfi)){
          arrAux = arrAux.filter(item => this.buildDateObject(item.FECHAEJECUCION) <= this.buildDateObject(feejfi));
          numFilters++;
        }else if(this.validDate(feejin) && this.validDate(feejfi)){
          arrAux = arrAux.filter(item => this.buildDateObject(item.FECHAEJECUCION) >= this.buildDateObject(feejin) && this.buildDateObject(item.FECHAEJECUCION) <= this.buildDateObject(feejfi));
          numFilters++;
        }

        if(usrEje != null && usrEje!= undefined && usrEje != ""){
          arrAux = arrAux.filter(item => this.getUserID(item.USUARIOEJECUCION) == usrEje);
          numFilters++;
        }

        if(numFilters > 0){
          this.hasFilters = true;
          this.dataSource = new MatTableDataSource(arrAux);
        }
      }
    });
  }

  getStatus(status: string): string{
    switch(status){
      case "Ejecucion": return "En ejecución"; break;
      case "Finalizado": return "Finalizado"; break;
      case "Cancelacion": return "Cancelado"; break;
    }
    
    return "";
  }

  validDate(date: Date | string | null | undefined): boolean{
    if(date == undefined || date == null || date == ""){
      return false;
    }else{
      return true;
    }
  }

  buildDateObject(date: string): Date{
    let dateArr = date.split('-');
    let dateObj = new Date(parseInt(dateArr[0]), parseInt(dateArr[1]) - 1, parseInt(dateArr[2]));
    
    return dateObj;
  }

  getUserID(user: string): string{
    let usrArr = user.split('(').reverse();
    return usrArr[0].replace(')', '');
  }

  verifyFilters(){
    if(this.hasFilters){
      this.deleteFilters();
    }else{
      this.openFilters();
    }
  }

  deleteFilters(){
    this.hasFilters = false;
    this.dataSource = new MatTableDataSource(this.workOrders);
  }
}
