import { Component, Inject, OnInit, ViewChild } from '@angular/core';
import { PriorityInterface } from '../../system-admin/system-params/system-params.component';
import { MatTableDataSource } from '@angular/material/table';
import { CorrectiveWorkOrdersListItem, CorrectiveWorkOrdersListResponse, NoMeasuresOrdersListItem, NoMeasuresOrdersListResponse } from '../../../interfaces/corrective-maintenance.interface';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { ActivatedRoute, Router } from '@angular/router';
import { SystemAdminService } from '../../../services/system-admin.service';
import { EncService } from '../../../services/enc.service';
import { CorrectiveMaintenanceService } from '../../../services/corrective-maintenance.service';
import { FunctionsService } from '../../../services/functions.service';
import { MatDialog } from '@angular/material/dialog';
import { ResourcesService } from '../../../services/resources.service';
import { SocketService } from '../../../services/socket.service';
import { UsersProfilesService } from '../../../services/users-profiles.service';
import { ProfileInterface } from '../../../interfaces/profile.interface';
import { lastValueFrom } from 'rxjs';
import { UserConsultResponse } from '../../../interfaces/user.interface';
import { Permissions } from '../../../interfaces/permissions.interface';
import { CorrectiveOrderDetailsComponent } from './corrective-order-details/corrective-order-details.component';
import { TransferOrderDialogComponent } from './transfer-order-dialog/transfer-order-dialog.component';
import { AlertComponent } from '../../resources/dialogs/alert/alert.component';
import { CommnetsDialogComponent } from './commnets-dialog/commnets-dialog.component';
import { StatusTimelineComponent } from './status-timeline/status-timeline.component';
import { NoMeasuresOrderValidationComponent } from './no-measures-order-validation/no-measures-order-validation.component';
import { NoMeasuresOrderDetailsComponent } from './no-measures-order-details/no-measures-order-details.component';
import { CloseNoMeasuresOrderComponent } from './close-no-measures-order/close-no-measures-order.component';
import { NoMeasuresOrderCloseValidationComponent } from './no-measures-order-close-validation/no-measures-order-close-validation.component';
import { NoMeasuresOrderReportComponent } from './no-measures-order-report/no-measures-order-report.component';
import { GdelService } from '../../../services/gdel.service';
import { DOCUMENT } from '@angular/common';
import { StaffSelectionComponent } from './staff-selection/staff-selection.component';

const ID_MODULE = "S002V01M09GMCO";
@Component({
    selector: 'app-operations-management',
    templateUrl: './operations-management.component.html',
    styleUrl: './operations-management.component.css',
    standalone: false
})
export class OperationsManagementComponent implements OnInit {
  isLoading: boolean;
  hasError: boolean;
  errorStr: string;

  orderPriorities: PriorityInterface[];

  public btnSmall: boolean = false;
  public txtBuscador:string;

  dataSource?: MatTableDataSource<any>;
  displayedColumns = ['ID', 'EQUIP', 'FECINI', 'FECFIN', 'CONT', 'TIPACT', 'PRIO', 'RESP', 'ESTADO', 'ACCIONES'];

  noMeasuresDataSource?: MatTableDataSource<any>;
  noMeasuresDisplayedColumns = ['IDRE', 'VERS', 'ESTA', 'FECH', 'USUA', 'ACCI'];

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

  dataURI: string | undefined;
  operationsConsultEnabled: boolean;
  manualActivationEnabled: boolean;
  workOrderGenerationEnabled: boolean;
  workOrderTransferEnabled: boolean;
  ordersType: string;

  constructor(
    @Inject(DOCUMENT) private _document: Document,
    private _activatedRoute: ActivatedRoute,
    private _router: Router,
    private _sysAdminService: SystemAdminService,
    private _encService: EncService,
    private _correctiveMaintenanceService: CorrectiveMaintenanceService,
    private _functionsService: FunctionsService,
    private _dialog: MatDialog,
    private _resourcesService: ResourcesService,
    private _socketService: SocketService,
    private _usersProfilesService: UsersProfilesService,
    private _gdelService: GdelService,
  ) {
    this._functionsService.consultModuleStatus(ID_MODULE);
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = '';

    this.orderPriorities = [];
    
    this.txtBuscador = '';
    this.btnSmall = window.innerWidth <= 1405;

    this.dataURI = undefined;
    this.operationsConsultEnabled = true;
    this.manualActivationEnabled = true;
    this.workOrderGenerationEnabled = true;
    this.workOrderTransferEnabled = true;
    this.ordersType = 'RCM';
  }

  ngOnInit(): void {
    this._activatedRoute.queryParams.subscribe(params => {
      let data = params['data'];
      this.dataURI = data;

      if(data == undefined){
        this.getOrderPriorities(false);
      }else{
        this.init(data);
      }
    });

    this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
      try{
        let idUser = localStorage.getItem('idusuario')!;
        let usrInfo: UserConsultResponse = await lastValueFrom(this._usersProfilesService.getUser(idUser, idUser, 1));
        
        if(usrInfo.error){
          this._resourcesService.openSnackBar('ERR_NPE000: Ocurrió un error inesperado (1).');
        }else{
          let idProfDec = await this._encService.decrypt(usrInfo.response.PERFIL);
          let currentProfile = await this._encService.decrypt(localStorage.getItem('perfil')!);

          if(idProfDec != currentProfile){
            this._router.navigate(['/sam/home']);
            return;
          }
          
          let profileUpdated = await this._encService.decrypt(`${profUpdEnc}`);
          if(profileUpdated == currentProfile){
            let profile = localStorage.getItem('perfil')!;
            let profInfo: ProfileInterface = await lastValueFrom(this._usersProfilesService.getProfile(
              profile,
              idUser,
              1
            ));

            let permArr = await this._functionsService.processPermissions(profInfo.response.PERMISOS.permissions);
            let modPerm = permArr.filter(item => item.id == 'S002V01M09GMCO');
            if(modPerm.length > 0){
              let subPerm = modPerm[0].children.filter(item => item.id == 'S002V01S01ORTR');
              if(subPerm.length > 0){
                let funPerm = subPerm[0].children.filter(item => item.id == 'S002V01F01GEOP');
                if(funPerm.length > 0){
                  let operationsConsultEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P01COOP');
                  if(operationsConsultEnabled.length > 0){
                    this.operationsConsultEnabled = operationsConsultEnabled[0].access > 0;
                  }
                }

                let manualActivationEnabled = subPerm[0].children.filter(item => item.id == 'S002V01F03ACMA');
                if(manualActivationEnabled.length > 0){
                  this.manualActivationEnabled = manualActivationEnabled[0].access > 0;
                }
                
                let workOrderGenerationEnabled = subPerm[0].children.filter(item => item.id == 'S002V01F04GEOT');
                if(workOrderGenerationEnabled.length > 0){
                  this.workOrderGenerationEnabled = workOrderGenerationEnabled[0].access > 0;
                }
  
                let workOrderTransferEnabled = subPerm[0].children.filter(item => item.id == 'S002V01F06TROT');
                if(workOrderTransferEnabled.length > 0){
                  this.workOrderTransferEnabled = workOrderTransferEnabled[0].access > 0;
                }
              }
            }
          }
        }
      }catch(error: any){
        if(error.error == undefined){
          this._resourcesService.openSnackBar('ERR_PAD001: Ocurrió un error inesperado (2).');
        }else if(error.error.msg == undefined){
          this._resourcesService.openSnackBar('ERR_PAD002: Ocurrió un error inesperado (3).');
        }else{
          this._resourcesService.openSnackBar(`ERR_PAD003: ${error.error.msg}`);
        }
      }
    });

    this._socketService.refreshModules().subscribe(async () => this._functionsService.consultModuleStatus(ID_MODULE));
  }

  async init(dataEnc: string){
    let dataDec = await this._encService.decrypt(dataEnc);
    let dataObj = JSON.parse(dataDec);

    let comesFromNotification = dataObj.actionFrom == 'notification';
    this.getOrderPriorities(comesFromNotification, dataObj.idOrder);
  }

  async getOrderPriorities(comesFromNotification: boolean, idOrder: string | null = null){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let orderPriorities = await lastValueFrom(this._sysAdminService.getOrderPriorities(idUser, 1));

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

      if(this.hasError){
        this.isLoading = false;
      }else{
        let prioritiesArr: PriorityInterface[] = [];
        for(const priority of orderPriorities.response.order_priorities as PriorityInterface[]){
          let idEnc = await this._encService.encrypt(priority.value);

          priority.label = `${priority.label} (${priority.value})`;
          priority.value = idEnc;

          prioritiesArr.push(priority);
        }

        this.orderPriorities = prioritiesArr;
        
        if(this.ordersType == 'RCM'){
          this.getworkOrders(comesFromNotification, idOrder);
        }else{
          this.getNoMeasuresOrders();
        }
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (4).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (5).';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async getworkOrders(comesFromNotification: boolean, idOrder: string | null = null){
    try{
      this.isLoading = true;
      this.hasError = false
      this.errorStr = '';

      let idUser = localStorage.getItem('idusuario')!;
      let workOrders: CorrectiveWorkOrdersListResponse = await lastValueFrom(this._correctiveMaintenanceService.getWorkOrders(idUser, 1));

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

      if(!this.hasError){
        let workOrdersArr: CorrectiveWorkOrdersListItem[] = [];
        for(const order of workOrders.response){
          let idOrderDec = await this._encService.decrypt(order.ID_ORDEN);
          order.ID_ORDEN = `Orden #${idOrderDec}`;

          let equipmentCodeDec = await this._encService.decrypt(order.CODIGO_EQUIPAMIENTO);
          order.TIPO_EQUIPAMIENTO = `${equipmentCodeDec} - ${order.TIPO_EQUIPAMIENTO}`;

          let idEquipmentDec = await this._encService.decrypt(order.ID_EQUIPAMIENTO);
          order.MODELO_EQUIPAMIENTO = `${order.MODELO_EQUIPAMIENTO} (${idEquipmentDec})`;
          order.FECHA_INICIO = this._functionsService.orderDate(order.FECHA_INICIO)!;

          let counterDec = await this._encService.decrypt(order.CONTADOR);
          order.CONTADOR = counterDec;

          let priorityObj = await this.getPriorityObj(order.PRIORIDAD);
          order.PRIORIDAD_OBJ = priorityObj == null ? undefined : priorityObj;

          if(order.FECHA_FIN != null){
            order.FECHA_FIN = this._functionsService.orderDate(order.FECHA_FIN)!;
          }
          
          workOrdersArr.push(order);
        }

        this.dataSource = new MatTableDataSource(workOrdersArr);
        this.dataSource.paginator = this.paginator!;
        this.dataSource.sort = this.sort!;
        
        let permissionsEnc = localStorage.getItem('permisos');
        let permissionsDec = '';
        if(permissionsEnc == '' || permissionsEnc == undefined || permissionsEnc == null){
          permissionsDec = '[]';
        }else{
          permissionsDec = await this._encService.decrypt(permissionsEnc!);
        }

        let permissionsArr: Permissions = JSON.parse(permissionsDec);
        if(permissionsArr.permissions != undefined){
          let modPerm = permissionsArr.permissions.filter(item => item.id == 'S002V01M09GMCO');
          if(modPerm.length > 0){
            let subPerm = modPerm[0].children.filter(item => item.id == 'S002V01S01ORTR');
            if(subPerm.length > 0){
              let funPerm = subPerm[0].children.filter(item => item.id == 'S002V01F01GEOP');
              if(funPerm.length > 0){
                let operationsConsultEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P01COOP');
                if(operationsConsultEnabled.length > 0){
                  this.operationsConsultEnabled = operationsConsultEnabled[0].access > 0;
                }
              }

              let manualActivationEnabled = subPerm[0].children.filter(item => item.id == 'S002V01F03ACMA');
              if(manualActivationEnabled.length > 0){
                this.manualActivationEnabled = manualActivationEnabled[0].access > 0;
              }
              
              let workOrderGenerationEnabled = subPerm[0].children.filter(item => item.id == 'S002V01F04GEOT');
              if(workOrderGenerationEnabled.length > 0){
                this.workOrderGenerationEnabled = workOrderGenerationEnabled[0].access > 0;
              }

              let workOrderTransferEnabled = subPerm[0].children.filter(item => item.id == 'S002V01F06TROT');
              if(workOrderTransferEnabled.length > 0){
                this.workOrderTransferEnabled = workOrderTransferEnabled[0].access > 0;
              }
            }
          }
        }
      }

      this.isLoading = false;
      if(comesFromNotification && idOrder != null){
        let idOrderDec = await this._encService.decrypt(idOrder);
        setTimeout(() => {
          this.applyFilter(`Orden #${idOrderDec}`, 'NOT');
        }, 250);
      }
    }catch(error: any){
      console.log(error);
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (6).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (7).';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async getNoMeasuresOrders(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let noMeasuresOrders: NoMeasuresOrdersListResponse = await lastValueFrom(this._correctiveMaintenanceService.getNoMeasuresOrders(idUser, 1));

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

      if(!this.hasError){
        let noMeasuresOrdersArr: NoMeasuresOrdersListItem[] = [];
        for(const order of noMeasuresOrders.response){
          let idRegDec = await this._encService.decrypt(order.ID_REGISTRO);
          order.ID_REGISTRO = idRegDec;

          let usrReg = await this._encService.decrypt(order.USUARIO_REGISTRO);
          order.USUARIO_REGISTRO = usrReg;

          let registerDate = this._functionsService.orderDate(order.FECHA_REGISTRO);
          order.FECHA_REGISTRO = registerDate;

          if(order.USUARIO_ACTUALIZACION != null){
            let usrUpd = await this._encService.decrypt(order.USUARIO_ACTUALIZACION);
            order.USUARIO_ACTUALIZACION = usrUpd == '-' ? null : usrUpd;
          }

          if(order.FECHA_ACTUALIZACION != null){
            let updateDate = this._functionsService.orderDate(order.FECHA_ACTUALIZACION);
            order.FECHA_ACTUALIZACION = updateDate;
          }

          noMeasuresOrdersArr.push(order);
        }

        this.noMeasuresDataSource = new MatTableDataSource(noMeasuresOrdersArr);
        this.noMeasuresDataSource.paginator = this.paginator!;
        this.noMeasuresDataSource.sort = this.sort!;
      }

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

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

  async getPriorityObj(priority: string): Promise<PriorityInterface | null>{
    let priorityStr = await this._encService.decrypt(priority);
    let priorityFilt: PriorityInterface | null = null;
    
    for(const priorityObj of this.orderPriorities){
      let idPriorityDec = await this._encService.decrypt(priorityObj.value);
      if(idPriorityDec == priorityStr){
        priorityFilt = priorityObj;
      }
    }

    return priorityFilt;
  }

  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();
    }
  }

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

  async openWorkOrder(type: string, idOrder: string | null){
    let idOrderEnc = '';
    if(idOrder != null){
      let idOrderStr = idOrder.replace('Orden #', '').trim();
      idOrderEnc = await this._encService.encrypt(idOrderStr);
    }else{
      idOrderEnc = await this._encService.encrypt('-');
    }
    
    this._router.navigate([`sam/GMCO/ORTR/GEOP/${type}`], {
      queryParams: {
        idOrder: idOrderEnc
      }
    });
  }

  async openWorkOrderWithoutMeasures(type: string, idOrder: string | null){
    let idOrderEnc = '';
    if(idOrder != null){
      let idOrderStr = idOrder.replace('Orden #', '').trim();
      idOrderEnc = await this._encService.encrypt(idOrderStr);
    }else{
      idOrderEnc = await this._encService.encrypt('-');
    }
    
    this._router.navigate([`sam/GMCO/ORTR/GEOP/${type}`], {
      queryParams: {
        idOrder: idOrderEnc
      }
    });
  }

  async openOrderDetails(idOrder: string){
    let idOrderStr = idOrder.replace('Orden #', '').trim();
    let idOrderEnc = await this._encService.encrypt(idOrderStr);
    this._dialog.open(CorrectiveOrderDetailsComponent, {
      width: '480px',
      maxWidth: '480px',
      data: {
        idOrder: idOrderEnc,
      }
    })
  }

  openTransferDialog(idOrder: string){
    let idOrderStr = idOrder.replace('Orden #', '').trim();
    let dialogRef = this._dialog.open(TransferOrderDialogComponent, {
      width: '420px',
      maxWidth: '420px',
      disableClose: true,
      data: {
        idOrder: idOrderStr
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != undefined && res != null && res != ''){
        let resArr = res.split('|');
        if(resArr.length < 3){
          this._resourcesService.openSnackBar('La acción seleccionada es inválida.');
        }else if(resArr[0] == 'transfer'){
          this.transferOrder(idOrder, resArr[1], resArr[2]);
        };
      }
    });
  }

  private async transferOrder(idOrder: string, idNewUser: string, type: string){
    try{
      let idOrderStr = idOrder.replace('Orden #', '').trim();
      let idUser = localStorage.getItem('idusuario')!;
      let idOrderEnc = await this._encService.encrypt(idOrderStr);
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_order', idOrderEnc);
      formData.append('id_new_user', idNewUser);
      formData.append('type', type.charAt(0).toUpperCase());

      await lastValueFrom(this._correctiveMaintenanceService.transferWorkOrder(formData));
      this._resourcesService.openSnackBar('La orden se transifirió correctamente.');
      this.getworkOrders(false);
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (10).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (11).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async openStaffSelectionDialog(idOrder: string){
    let idOrderStr = idOrder.replace('Orden #', '').trim();
    let idOrderEnc = await this._encService.encrypt(idOrderStr);
    let dialogRef = this._dialog.open(StaffSelectionComponent, {
      disableClose: true,
      width: '540px',
      maxWidth: '540px',
      data: {
        idOrder: idOrderEnc,
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        this.approveWorkOrder(idOrderEnc, res);
      }
    });
  }

  openConfirmDialog(action: string, idOrder: string){
    let idOrderStr = idOrder.replace('Orden #', '').trim();
    let actionStr = '';
    let desc2 = '';

    switch(action){
      case 'DEL':
        actionStr = 'eliminar';
        desc2 = 'Esta acción no se puede deshacer.';
      break;
      case 'APR':
        actionStr = 'aprobar';
        desc2 = 'Esta acción enviará la OT por notificación a los involucrados.';
      break;
    }

    let dialogRef = this._dialog.open(AlertComponent, {
      width: '420px',
      maxWidth: '420px',
      disableClose: true,
      data: {
        title: 'Confirmación',
        icon: 'warning',
        description: `¿Está seguro de ${actionStr} la orden de mantenimiento correctivo #${idOrderStr}?`,
        description2: desc2
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res == true){
        switch(action){
          case 'DEL': 
            this.deleteWorkOrder(idOrder);
          break;
          case 'APR':
          break;
        }
      }
    });
  }

  private async deleteWorkOrder(idOrder: string){
    try{
      let idOrderStr = idOrder.replace('Orden #', '').trim();
      let idOrderEnc = await this._encService.encrypt(idOrderStr);
      let idUser = localStorage.getItem('idusuario')!;
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_order', idOrderEnc);

      await lastValueFrom(this._correctiveMaintenanceService.deleteWorkOrder(formData));
      this._resourcesService.openSnackBar('La orden de trabajo se eliminó correctamente.');
      this.getworkOrders(false);
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (12).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (13).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  private async approveWorkOrder(idOrder: string, config: 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('config', config);
      console.log(formData);

      await lastValueFrom(this._correctiveMaintenanceService.approveWorkOrder(formData));
      this._resourcesService.openSnackBar('La orden de trabajo se aprobó correctamente.');
      this.getworkOrders(false);
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (14).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (15).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  openCommentsDialog(idOrder: string, status: string){
    let idOrderStr = idOrder.replace('Orden #', '').trim();
    let dialogRef = this._dialog.open(CommnetsDialogComponent, {
      width: '480px',
      maxWidth: '480px',
      disableClose: true,
      data: {
        idOrder: idOrderStr,
        status: status,
      }
    });
    
    dialogRef.afterClosed().subscribe(res => {
      if(res != undefined && res != null && res != ''){
        this.updateWorkOrderStatus(idOrder, status, res);
      }
    });
  }

  private async updateWorkOrderStatus(idOrder: string, status: string, comments: string){
    try{
      let idOrderStr = idOrder.replace('Orden #', '').trim();
      let idUser = localStorage.getItem('idusuario')!;
      let idOrderEnc = await this._encService.encrypt(idOrderStr);
      let statusKey = status.toUpperCase().substring(0, 2);
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_order', idOrderEnc);
      formData.append('status', statusKey);
      formData.append('comments', comments);

      let response = await lastValueFrom(this._correctiveMaintenanceService.updateWorkOrderStatus(formData));
      
      this._resourcesService.openSnackBar(response.msg);
      this.getworkOrders(false);
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (16).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (17).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.getworkOrders(false);
    }
  }

  alertStartOrder(idOrder: string){
    let idOrderStr = idOrder.replace('Orden #', '').trim();
    let dialogRef = this._dialog.open(AlertComponent, {
      width: '420px',
      maxWidth: '420px',
      disableClose: true,
      data: {
        title: 'Confirmación',
        icon: 'warning',
        description: `¿Está seguro de iniciar la ejecución la orden #${idOrderStr}?`
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res == true){
        this.verifyOrderStatus(idOrderStr);
      }
    });
  }

  private async verifyOrderStatus(idOrder: string){
    try{
      this._resourcesService.openSnackBar('Verificando orden...');

      let idOrderEnc = await this._encService.encrypt(idOrder);
      let idUser = localStorage.getItem('idusuario')!;
      let orderAttendance = await lastValueFrom(this._correctiveMaintenanceService.getWorkOrderAttendance(
        idOrderEnc,
        idUser,
        1
      ));

      if(orderAttendance.error){
        this._resourcesService.openSnackBar(orderAttendance.msg);
      }else if(orderAttendance.response.length <= 0){
        this._resourcesService.openSnackBar('Ninguno de los operarios involucrados ha respondido a la solicitud.');
      }else{
        let orderStaff = await lastValueFrom(this._correctiveMaintenanceService.getWorkOrderStaff(
          idOrderEnc,
          idUser,
          1
        ));

        if(orderAttendance.error){
          this._resourcesService.openSnackBar(orderAttendance.msg);
        }else{
          let neededUsers = 0;
          for(const item of orderStaff.response){
            neededUsers += item.CANT;
          }

          let startedUsers = 0;
          for(const item of orderAttendance.response){
            if(item.RESPUESTA == "A") startedUsers++;
          }

          if(neededUsers > startedUsers){
            this._resourcesService.openSnackBar('Algunos operarios involucrados no han respondido a la solicitud.');
          }else{
            this.startOrder(idOrder);
          }
        }
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  alertValidateClosedOrder(idOrder: string){
    let idOrderStr = idOrder.replace('Orden #', '').trim();
    let dialogRef = this._dialog.open(AlertComponent, {
      width: '420px',
      maxWidth: '420px',
      disableClose: true,
      data: {
        title: 'Confirmación',
        icon: 'warning',
        description: `¿Está seguro de validar el cierre de la orden #${idOrderStr}?`
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res == true){
        this.validateCloseOrder(idOrderStr);
      }
    });
  }

  private async validateCloseOrder(idOrder: string){
    try{
      let idOrderStr = idOrder.replace('Orden #', '').trim();
      let idUser = localStorage.getItem('idusuario')!;
      let idOrderEnc = await this._encService.encrypt(idOrderStr);
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_order', idOrderEnc);

      await lastValueFrom(this._correctiveMaintenanceService.closeWorkOrder(formData));
      
      this._resourcesService.openSnackBar("El cierrre de la orden se validó correctamente.");
      this.getworkOrders(false);
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async startOrder(idOrder: string){
    try{
      let idOrderStr = idOrder.replace('Orden #', '').trim();
      let idUser = localStorage.getItem('idusuario')!;
      let idOrderEnc = await this._encService.encrypt(idOrderStr);
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_order', idOrderEnc);
      
      await lastValueFrom(this._correctiveMaintenanceService.startWorkOrder(formData));

      this._resourcesService.openSnackBar('La ejecución de la orden de trabajo se inició correctamente.');
      this.getworkOrders(false);
    }catch(error: any){
      if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (18).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (19).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.getworkOrders(false);
    }
  }

  openStatusTimeline(idOrder: string){
    let idOrderStr = idOrder.replace('Orden #', '').trim();
    this._dialog.open(StatusTimelineComponent, {
      width: '480px',
      maxWidth: '480px',
      data: {
        idOrder: idOrderStr
      }
    });
  }

  changeOperationsTable(){
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = '';

    if(this.dataURI == undefined){
      this.getOrderPriorities(false);
    }else{
      this.init(this.dataURI);
    }
  }

  async editOrder(idOrder: string){
    let idOrderEnc = await this._encService.encrypt(idOrder);
    
    this._router.navigate([`sam/GMCO/ORTR/GEOP/editar-sin-mediciones`], {
      queryParams: {
        idOrder: idOrderEnc
      }
    });
  }

  openValidationDialog(idOrder: string){
    let dialogRef = this._dialog.open(NoMeasuresOrderValidationComponent, {
      disableClose: true,
      width: '420px',
      maxWidth: '420px',
      data: {
        idOrder: idOrder,
      }
    });

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

  private async validateNoMeasuresOrder(idOrder: string, dataEnc: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let dataDec = await this._encService.decrypt(dataEnc);
      let dataObj = JSON.parse(dataDec);
      let idOrderEnc = await this._encService.encrypt(idOrder);
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_order', idOrderEnc);
      formData.append('validated_by', dataObj.validatedByControl);
      formData.append('record', dataObj.recordControl);
      formData.append('validation', dataObj.validation);
      
      await lastValueFrom(this._correctiveMaintenanceService.noMeasuresOrderValidation(formData));

      this._resourcesService.openSnackBar('El estado de la validación de la orden se actualizó correctamente.');
      this.changeOperationsTable();
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (20).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (21).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  openConfirmDialogNoMeasures(action: string, idOrder: string){
    let actionStr = '';
    let desc2 = '';

    switch(action){
      case 'DEL':
        actionStr = 'eliminar';
        desc2 = 'Esta acción no se puede deshacer.';
      break;
      case 'APR':
        actionStr = 'aprobar';
        desc2 = 'Esta acción enviará la OT por notificación a los involucrados.';
      break;
    }

    let dialogRef = this._dialog.open(AlertComponent, {
      width: '420px',
      maxWidth: '420px',
      disableClose: true,
      data: {
        title: 'Confirmación',
        icon: 'warning',
        description: `¿Está seguro de ${actionStr} la orden #${idOrder}?`,
        description2: desc2
      }
    });
    
    dialogRef.afterClosed().subscribe(res => {
      console.log(res);
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res == true){
        switch(action){
          case 'DEL': 
            this.deleteNoMeasuresOrder(idOrder);
          break;
          case 'APR':
            //this.approveWorkOrder(idOrder);
          break;
        }
      }
    });
  }

  private async deleteNoMeasuresOrder(idOrder: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let idOrderEnc = await this._encService.encrypt(idOrder);
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_order', idOrderEnc);

      await lastValueFrom(this._correctiveMaintenanceService.deleteNoMeasuresOrder(formData));

      this._resourcesService.openSnackBar('La orden se eliminó correctamente.');
      this.changeOperationsTable();
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (22).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (23).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async openNoMeasuresOrderDetails(idOrder: string){
    let idOrderEnc = await this._encService.encrypt(idOrder);
    this._dialog.open(NoMeasuresOrderDetailsComponent, {
      width: '520px',
      maxWidth: '520px',
      data: {
        idOrder: idOrderEnc,
      }
    });
  }

  openEvidenceToClose(idOrder: string){
    let dialogRef = this._dialog.open(CloseNoMeasuresOrderComponent, {
      width: '1080px',
      maxWidth: '1080px',
      disableClose: true,
      data: {
        idOrder: idOrder,
      }
    });

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

  private async closeNoMeasuresOrder(idOrder: string, dataEnc: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let dataDec = await this._encService.decrypt(dataEnc);
      let dataObj = JSON.parse(dataDec);
      let activitiesDec = await this._encService.decrypt(dataObj.activities);
      let evidenceDec = await this._encService.decrypt(dataObj.evidence);
      let idOrderEnc = await this._encService.encrypt(idOrder);
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_order', idOrderEnc);
      formData.append('evidence', evidenceDec);
      formData.append('activities', activitiesDec);

      await lastValueFrom(this._correctiveMaintenanceService.closeNoMeasuresOrder(formData));

      this._resourcesService.openSnackBar('La orden se cerró correctamente.');
      this.changeOperationsTable();
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (24).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (25).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async openValidateNoMeasuresOrderClosed(idOrder: string){
    let idOrderEnc = await this._encService.encrypt(idOrder);
    let dialogRef = this._dialog.open(NoMeasuresOrderCloseValidationComponent, {
      width: '1024px',
      maxWidth: '1024px',
      disableClose: true,
      data: {
        idOrder: idOrderEnc
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        let resArr = res.split('-');
        if(resArr.length == 2){
          this.validateNoMeasuresOrderClosed(idOrder, resArr[0], resArr[1]);
        }
      }
    });
  }

  private async validateNoMeasuresOrderClosed(idOrder: string, validation: string, validatedBy: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let idOrderEnc = await this._encService.encrypt(idOrder);
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_order', idOrderEnc);
      formData.append('validation', validation);
      formData.append('validated_by', validatedBy);
      
      await lastValueFrom(this._correctiveMaintenanceService.closedNoMeasuresOrderValidation(formData));

      this._resourcesService.openSnackBar('El estado de la validación de la orden cerrada se actualizó correctamente.');
      this.changeOperationsTable();
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (26).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (27).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async openNoMeasuresReportGeneration(idOrder: string, reportType: string){
    let idOrderEnc = await this._encService.encrypt(idOrder);
    let dialogRef = this._dialog.open(NoMeasuresOrderReportComponent, {
      width: '1440px',
      maxWidth: '1440px',
      disableClose: true,
      data: {
        idOrder: idOrderEnc,
        reportType: reportType,
      }
    });
    
    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        this.generateNoMeasuresReport(idOrderEnc, reportType, res);
      }
    });
  }

  private async generateNoMeasuresReport(idOrder: string, reportType: string, reportData: string){
    try{
      this._resourcesService.openSnackBar('Generando reporte...');

      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('report_type', reportType);
      formData.append('report_data', reportData);
      console.log(formData);

      let res = await lastValueFrom(this._correctiveMaintenanceService.generateNoMeasuresReport(formData));
      if(res.error){
        this._resourcesService.openSnackBar(res.msg);
      }else{
        let fileIDEnc = await this._encService.encrypt(res.response.fileID);
        let download = this._document.getElementById(`download`) as HTMLAnchorElement;
        let downloadToken = await lastValueFrom(this._gdelService.getDownloadToken(
          fileIDEnc,
          idUser,
          1
        ));
    
        download.href = `http://git.ittec.mx/sam/public/api/download-file/${downloadToken.response.TOKEN}/${idUser}/1`;
        download.download = res.response.fileID;
        download.click();
  
        this._resourcesService.openSnackBar('Descarga realizada.');
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (28).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (29).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }
}
