import { Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
import { EquipmentDetails, EquipmentDetailsResponse, EquipmentsListItem, EquipmentsListResponse } from '../../../../interfaces/equipment-management.interface';
import { ResponseDataGetToolsAndSpare, ToolsAndSpare } from '../../../../interfaces/inventory-management/tools-and-spare.interface';
import { TempFileInfo } from '../../../../interfaces/temp-file-info.interface';
import { ActivatorByType, ActivatorsByTypeResponse } from '../../../../interfaces/activators-by-type.interface';
import { PriorityInterface } from '../../../system-admin/system-params/system-params.component';
import { MatTableDataSource } from '@angular/material/table';
import { SpecialtiesListItem, SpecialtiesListResponse } from '../../../../interfaces/specialties.interface';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { EmployeesListItem } from '../../../../interfaces/personal-managment/employee.interface';
import { SubcontratistItem } from '../../../../interfaces/personal-managment/subcontratists.interface';
import { PreventiveWorkOrder, PreventiveWorkOrderResponse } from '../../../../interfaces/preventive-work-order.interface';
import { debounceTime, distinctUntilChanged, filter, lastValueFrom, Observable, switchMap, tap } from 'rxjs';
import { DOCUMENT } from '@angular/common';
import { ActivatedRoute, Router } from '@angular/router';
import { EncService } from '../../../../services/enc.service';
import { MatDialog } from '@angular/material/dialog';
import { CountersActivatorsService } from '../../../../services/counters-activators.service';
import { PreventiveMaintenanceService } from '../../../../services/preventive-maintenance.service';
import { SocketService } from '../../../../services/socket.service';
import { UsersProfilesService } from '../../../../services/users-profiles.service';
import { GdelService } from '../../../../services/gdel.service';
import { ResourcesService } from '../../../../services/resources.service';
import { SystemAdminService } from '../../../../services/system-admin.service';
import { EquipmentManagementService } from '../../../../services/equipment-management.service';
import { InterventionService } from '../../../../services/personal-management/intervention.service';
import { FunctionsService } from '../../../../services/functions.service';
import { Permissions } from '../../../../interfaces/permissions.interface';
import { UserConsultResponse } from '../../../../interfaces/user.interface';
import { ProfileInterface } from '../../../../interfaces/profile.interface';
import { InventoryManagementService } from '../../../../services/inventory-management/inventory-management.service';
import { ActivatorDialogComponent } from '../../../counters-activators/activators-management/activator-dialog/activator-dialog.component';
import { TimePickerComponent } from '../../../resources/dialogs/time-picker/time-picker.component';
import { GraphicEquipmentSearchComponent } from '../../../equipment-management/graphic-equipment-search/graphic-equipment-search.component';
import { EquipmentDetailsDialogComponent } from '../../../equipment-management/new-equipment/equipment-details-dialog/equipment-details-dialog.component';
import { EquipmentDocumentsComponent } from '../../../equipment-management/equipment-documents/equipment-documents.component';
import { NewInstructionComponent } from './new-instruction/new-instruction.component';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { AlertComponent } from '../../../resources/dialogs/alert/alert.component';
import { SearchFileDialogComponent } from '../../../gdel/search-file-dialog/search-file-dialog.component';
import { FindedFile } from '../../../../interfaces/finded-files.interface';
import { availableFiles } from '../../../../../environments/environment.prod';
import { UploadMaintenancePlanComponent } from './upload-maintenance-plan/upload-maintenance-plan.component';

const ID_MODULE = "S002V01M10GMPR";
export interface Instruction{
  ID: string,
  INSTRUCCION: string,
  DURACION: number,
  INICIO: string,
  FIN: string,
  COSTO: number,
  ESPECIALIDADES: '',
  ISFROMFILE: boolean,
  IDFILE: string,
}
@Component({
    selector: 'app-new-work-order',
    templateUrl: './new-work-order.component.html',
    styleUrl: './new-work-order.component.css',
    standalone: false
})
export class NewWorkOrderComponent implements OnInit {
  isUploading: boolean;
  isLoading: boolean;
  hasError: boolean;
  isNew: boolean;
  loadingActivators: boolean;
  searchingEquipments: boolean;
  disabledStartHour: boolean;
  disabledEndHour: boolean;
  errorStr: string;
  action: string;
  idOrder: string | null;
  hoursArr: any[];
  equipments: EquipmentsListItem[];
  tools: ToolsAndSpare[];
  spareParts: ToolsAndSpare[];
  attached: TempFileInfo[];
  toolsParts: ToolsAndSpare[];
  activators: ActivatorByType[];
  orderPriorities: PriorityInterface[];

  dataSource: MatTableDataSource<EquipmentDetails>;
  displayedColumns = ['EQUIPO', 'ACCIONES'];

  @ViewChild('file') private uploader?: ElementRef;

  activCols: number;
  datesCols: number;
  timesCols: number;
  toolsCols: number;
  screenSize: number;

  specialtiesDataSource: MatTableDataSource<SpecialtiesListItem>;
  specialtiesDisplayedColumns = ['ITEM', 'CANTREQ'];

  toolsDataSource?: MatTableDataSource<ToolsAndSpare>;
  toolsDisplayedColumns = ['ITEM', 'TIPO', 'CANTDISP', 'CANTNEC', 'CANTRES'];

  startDate: Date | null;
  endDate: Date | null;

  teamsConf: any;
  toolsConf: any;
  partsConf: any;

  registerOrderEnabled: boolean;
  selectEquipmentEnabled: boolean;
  selectTeamsEnabled: boolean;

  orderFormGroup: FormGroup;
  instructions: Instruction[];

  dayNames = ['Domingos', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábados'];
  MONTHS = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
  deleteFilesDisabled: boolean;

  specialties: SpecialtiesListItem[];
  employees: EmployeesListItem[];
  subcontratists: SubcontratistItem[];
  workTeams: any[];
  workOrder: PreventiveWorkOrder | null;

  autoCompleteEquipments: string[];
  activatorConfigStr: string;
  filteredEquipments!: Observable<string[]>;

  constructor(
    @Inject(DOCUMENT) private _document: Document,
    private _activatedRoute: ActivatedRoute,
    private _encService: EncService,
    private _dialog: MatDialog,
    private _countersActivatorsService: CountersActivatorsService,
    private _prevMaintService: PreventiveMaintenanceService,
    private _socketService: SocketService,
    private _usersProfilesSevice: UsersProfilesService, 
    private _router: Router,
    private _gdelService: GdelService,
    private _resourcesService: ResourcesService,
    private _sysAdminService: SystemAdminService,
    private _equipmentsService: EquipmentManagementService,
    private _inventoryManagementService: InventoryManagementService,
    private _interventionService: InterventionService,
    private _functionsService: FunctionsService,
  ) { 
    this._functionsService.consultModuleStatus(ID_MODULE);
    this.isUploading = false;
    this.isLoading = true;
    this.hasError = false;
    this.isNew = false;
    this.loadingActivators = false;
    this.searchingEquipments = false;
    this.disabledStartHour = true;
    this.disabledEndHour = true;
    this.errorStr = "";
    this.action = "";
    this.idOrder = null;
    this.hoursArr = [];
    this.dataSource = new MatTableDataSource();
    this.equipments = [];
    this.tools = [];
    this.spareParts = [];
    this.attached = [];
    this.activators = [];
    this.orderPriorities = [];

    this.activCols = window.innerWidth > 840 ? 2 : 1;
    this.datesCols = window.innerWidth > 1164 ? 4 : window.innerWidth > 840 ? 2 : 1;
    this.timesCols = window.innerWidth > 1164 ? 3 : window.innerWidth > 840 ? 2 : 1;
    this.toolsCols = window.innerWidth > 840 ? 2 : 1;
    this.screenSize = window.innerWidth;
    
    this.specialtiesDataSource = new MatTableDataSource();
    this.toolsDataSource = new MatTableDataSource();
    this.toolsParts = [];

    this.startDate = null;
    this.endDate = null;

    this.teamsConf = {};
    this.toolsConf = {};
    this.partsConf = {};
    
    this.registerOrderEnabled = true;
    this.selectEquipmentEnabled = true;
    this.selectTeamsEnabled = true;

    this.orderFormGroup = new FormGroup({
      activatorTypeControl: new FormControl('', Validators.required),
      activatorControl: new FormControl({value: 0, disabled: true}, Validators.required),
      startDateControl: new FormControl({value: this.startDate, disabled: true}),
      startHourControl: new FormControl({value: '', disabled: true}),
      endDateControl: new FormControl({value: this.endDate, disabled: true}),
      endHourControl: new FormControl({value: '', disabled: true}),
      equipmentControl: new FormControl('', Validators.required),
      descriptionControl: new FormControl('', [Validators.required, Validators.minLength(15)]),
      inmTimeControl: new FormControl('', [Validators.required, Validators.pattern('[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')]),
      totalTimeControl: new FormControl({disabled: true, value: ''}, [Validators.required, Validators.pattern('[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')]),
      toolsControl: new FormControl([], Validators.required),
      sparePartsControl: new FormControl([], Validators.required),
      analisisControl: new FormControl({value: '', disabled: true}),
      clasificationControl: new FormControl('', [Validators.required, Validators.maxLength(100)]),
      staffControl: new FormControl([], Validators.required),
    });

    this.instructions = [];
    this.deleteFilesDisabled = false;

    this.specialties = [];
    this.employees = [];
    this.subcontratists = [];
    this.workTeams = [];
    this.workOrder = null;

    this.autoCompleteEquipments = [];
    this.activatorConfigStr = '';
  }

  ngOnInit() {
    this._activatedRoute.queryParams.subscribe(res => {
      let params = res['idOrder'];
      if(params == undefined){
        this.isNew = true;
        this.action = 'Registrar';
        this.idOrder = null;
      }else{
        this.isNew = false;
        this.action = 'Editar';
        this.idOrder = params;
      }

      this.getProfileAccess(params);
    });

    this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
      let idUser = localStorage.getItem('idusuario')!;
      let usrInfo: UserConsultResponse = await lastValueFrom(this._usersProfilesSevice.getUser(idUser, idUser, 1));
      let currentProfile = await this._encService.decrypt(localStorage.getItem('perfil')!);

      if(currentProfile != usrInfo.response.PERFIL){
        this._router.navigate(['/sam/home']);
      }

      let profileUpdated = await this._encService.decrypt(`${profUpdEnc}`);
      if(profileUpdated == currentProfile){
        try{
          let profile = localStorage.getItem('perfil')!;
          let profInfo: ProfileInterface = await lastValueFrom(this._usersProfilesSevice.getProfile(
            profile,
            idUser,
            1
          ));

          let modPerm = profInfo.response.PERMISOS.permissions.filter(item => item.id == 'S002V01M10GMPR')[0];
          let subPerm = modPerm.children.filter(item => item.id == 'S002V01S01ORTR')[0];
          let funPerm = subPerm.children.filter(item => item.id == 'S002V01F01COTP')[0];
    
          this.registerOrderEnabled = funPerm.children.filter(item => item.id == 'S002V01P02ROTP')[0].access > 0;
          this.selectEquipmentEnabled = subPerm.children.filter(item => item.id == 'S002V01F02CLDE')[0].access > 0;
          this.selectTeamsEnabled = subPerm.children.filter(item => item.id == 'S002V01F04DOCT')[0].access > 0;

          if(this.selectEquipmentEnabled){
            this.orderFormGroup.controls['equipmentControl'].enable();
          }else{
            this.orderFormGroup.controls['equipmentControl'].disable();
          }
        }catch(error: any){
          if(error.error == undefined){
            this._resourcesService.openSnackBar('0003: Ocurrió un error al actualizar su perfil');
          }else if(error.error.msg == undefined){
            this._resourcesService.openSnackBar('0004: Ocurrió un error al actualizar su perfil');
          }else{
            this._resourcesService.openSnackBar(error.error.msg);
          }
        }
      }
    });

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

    this.orderFormGroup.controls['equipmentControl'].valueChanges.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      filter(value => value ? true : false),
      tap(() => this.searchingEquipments = true),
      switchMap(value => this._filterEquipments(value))
    ).subscribe(autoCompleteList => {
      this.autoCompleteEquipments = autoCompleteList;
    });

    this.orderFormGroup.controls['startDateControl'].valueChanges.subscribe((_) => {
      this.verifyDateTime('start');
    });

    this.orderFormGroup.controls['endDateControl'].valueChanges.subscribe((_) => {
      this.verifyDateTime('end');
    });
  }

  private async _filterEquipments(value: string): Promise<string[]>{
    let equipmentsStr: string[] = [];
    let idUser = localStorage.getItem('idusuario')!;
    let equipments: EquipmentsListResponse = await lastValueFrom(this._equipmentsService.equipmentConsultFiltered(value, idUser, 1));

    if(equipments.error){
      this._resourcesService.openSnackBar(equipments.msg);
    }else{
      for(const equipment of equipments.response){
        let codeDec = await this._encService.decrypt(equipment.CODIGO);
        let idDec = await this._encService.decrypt(equipment.ID_EQUIPO);

        equipmentsStr.push(`${codeDec} - ${equipment.TIPO} - ${equipment.MODELO} (${idDec})`);
      }
    }

    this.searchingEquipments = false;
    return equipmentsStr;
  }
  
  verifyDateTime(type: string){
    let startDate = this.orderFormGroup.controls['startDateControl'].value;
    let startHour = this.orderFormGroup.controls['startHourControl'].value;
    let endDate = this.orderFormGroup.controls['endDateControl'].value;
    let endHour = this.orderFormGroup.controls['endHourControl'].value;

    if(type == 'start' && startHour != null && startDate != null){
      let startDateStr = `${startDate.getFullYear()}-${startDate.getMonth() + 1}-${startDate.getDate()}`;
      let startHourArr = `${startHour}`.split(' ');
      if(startHourArr.length == 2){
        let startHour = startHourArr[0].split(':');
        let startHourNum = parseInt(startHour[0]);
        
        if(startHourArr[1] == 'PM'){
          startHourNum = startHourNum < 12 ? startHourNum + 12 : startHourNum;
        }

        let startHourStr = startHourNum < 10 ? `0${startHourNum}` : `${startHourNum}`;
        let startTimeStr = `${startHourStr}:${startHour[1]}:00`;

        let startDateTimeStr = `${startDateStr} ${startTimeStr}`;
        let startDateTime = new Date(startDateTimeStr);
        let startTimestamp = startDateTime.getTime();

        if(endHour != null && endDate != null){
          let endDateStr = `${endDate.getFullYear()}-${endDate.getMonth() + 1}-${endDate.getDate()}`;
          let endHourArr = `${endHour}`.split(' ');
          if(endHourArr.length == 2){
            let endHour = endHourArr[0].split(':');
            let endHourNum = parseInt(endHour[0]);
            
            if(endHourArr[1] == 'PM'){
              endHourNum = endHourNum < 12 ? endHourNum + 12 : endHourNum;
            }
    
            let endHourStr = endHourNum < 10 ? `0${endHourNum}` : `${endHourNum}`;
            let endTimeStr = `${endHourStr}:${endHour[1]}:00`;
    
            let endDateTimeStr = `${endDateStr} ${endTimeStr}`;
            let endDateTime = new Date(endDateTimeStr);
            let endTimestamp = endDateTime.getTime();
        
            if(startTimestamp > endTimestamp){
              this._resourcesService.openSnackBar('La hora de inicio no puede ser mayor a la hora de término.');
              setTimeout(() => this.orderFormGroup.controls['startHourControl'].setValue(null), 250);
            }
          }
        }
      }
    }else if(type == 'end' && endHour != null && endDate != null){
      let endDateStr = `${endDate.getFullYear()}-${endDate.getMonth() + 1}-${endDate.getDate()}`;
      let endHourArr = `${endHour}`.split(' ');
      if(endHourArr.length == 2){
        let endHour = endHourArr[0].split(':');
        let endHourNum = parseInt(endHour[0]);
        
        if(endHourArr[1] == 'PM'){
          endHourNum = endHourNum < 12 ? endHourNum + 12 : endHourNum;
        }

        let endHourStr = endHourNum < 10 ? `0${endHourNum}` : `${endHourNum}`;
        let endTimeStr = `${endHourStr}:${endHour[1]}:00`;

        let endDateTimeStr = `${endDateStr} ${endTimeStr}`;
        let endDateTime = new Date(endDateTimeStr);
        let endTimestamp = endDateTime.getTime();

        if(startHour != null && startDate != null){
          let startDateStr = `${startDate.getFullYear()}-${startDate.getMonth() + 1}-${startDate.getDate()}`;
          let startHourArr = `${startHour}`.split(' ');
          if(startHourArr.length == 2){
            let startHour = startHourArr[0].split(':');
            let startHourNum = parseInt(startHour[0]);
            
            if(startHourArr[1] == 'PM'){
              startHourNum = startHourNum < 12 ? startHourNum + 12 : startHourNum;
            }
    
            let startHourStr = startHourNum < 10 ? `0${startHourNum}` : `${startHourNum}`;
            let startTimeStr = `${startHourStr}:${startHour[1]}:00`;
    
            let startDateTimeStr = `${startDateStr} ${startTimeStr}`;
            let startDateTime = new Date(startDateTimeStr);
            let startTimestamp = startDateTime.getTime();

            if(endTimestamp < startTimestamp){
              this._resourcesService.openSnackBar('La hora de término no puede ser menor a la hora de inicio.');
              setTimeout(() => this.orderFormGroup.controls['endHourControl'].setValue(null), 250);
            }
          }
        }
      }
    }
  }

  async getProfileAccess(idOrder: string){
    try{
      let permissionsEnc = localStorage.getItem('permisos');
      let permissionsDec = await this._encService.decrypt(permissionsEnc!);
      let permissionsArr: Permissions = JSON.parse(permissionsDec);

      let modPerm = permissionsArr.permissions.filter(item => item.id == 'S002V01M10GMPR')[0];
      let subPerm = modPerm.children.filter(item => item.id == 'S002V01S01ORTR')[0];
      let funPerm = subPerm.children.filter(item => item.id == 'S002V01F01COTP')[0];

      this.registerOrderEnabled = funPerm.children.filter(item => item.id == 'S002V01P02ROTP')[0].access > 0;
      this.selectEquipmentEnabled = subPerm.children.filter(item => item.id == 'S002V01F02CLDE')[0].access > 0;
      this.selectTeamsEnabled = subPerm.children.filter(item => item.id == 'S002V01F04DOCT')[0].access > 0;

      if(this.selectEquipmentEnabled){
        this.orderFormGroup.controls['equipmentControl'].enable();
      }else{
        this.orderFormGroup.controls['equipmentControl'].disable();
      }

      if(this.isNew){
        this.getOrderPriorities();
      }else{
        this.getWorkOrder(idOrder);
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (1).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (2).';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async getOrderPriorities(){
    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 priorityEnc = await this._encService.encrypt(priority.value);

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

          prioritiesArr.push(priority);
        }
        
        this.orderPriorities = prioritiesArr;
        if(this.workOrder != null && this.workOrder!.ACTIVADOR != null && this.workOrder!.TIPOACTIVADOR != null){
          let activatorTypeInd = this.workOrder!.TIPOACTIVADOR!.substring(0, 2).toUpperCase();
          this.orderFormGroup.controls['activatorTypeControl'].setValue(activatorTypeInd);

          let activator = await this._encService.decrypt(this.workOrder!.ACTIVADOR!);
          this.getActivatorsByType(activatorTypeInd, activator);
        } 

        this._getToolsAndSpare();
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (3).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (4).';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async getWorkOrder(idOrder: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let order: PreventiveWorkOrderResponse = await lastValueFrom(this._prevMaintService.getWorkOrder(idOrder, idUser, 1));

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

      if(this.hasError){
        this.isLoading = false;
      }else{
        if(order.response.ID_EQUIPAMIENTO != null){
          let equipmentCodeDec = await this._encService.decrypt(order.response.EQUIPAMIENTO);
          let equipmentIDDEc = await this._encService.decrypt(order.response.ID_EQUIPAMIENTO);
          let equipmentStr = `${equipmentCodeDec} - ${order.response.TIPO_EQUIPAMIENTO} - ${order.response.MODELO_EQUIPAMIENTO} (${equipmentIDDEc})`;

          this.orderFormGroup.controls['equipmentControl'].setValue(equipmentStr);
        }

        this.orderFormGroup.controls['descriptionControl'].setValue(order.response.DESCRIPCION);

        let instructionsArr: Instruction[] = JSON.parse(order.response.INSTRUCCIONES);
        for(const instruction of instructionsArr){
          instruction.ID = await this._encService.decrypt(instruction.ID);
        }

        this.instructions = instructionsArr;
        this.orderFormGroup.controls['totalTimeControl'].setValue(`${order.response.DURACIONTOTAL}`);
        this.orderFormGroup.controls['inmTimeControl'].setValue(`${order.response.TIEMPOINMOESTI}`);
        this.orderFormGroup.controls['clasificationControl'].setValue(`${order.response.CLASIFICACION}`);

        if(order.response.DOCUMENTOS != null){
          let attached = JSON.parse(order.response.DOCUMENTOS!);
          attached.forEach((document: TempFileInfo) => {
            this.attached.push(document);
          });
        }

        this.workOrder = order.response;
        this.getOrderPriorities();
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (5).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (6).';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async getActivatorsByType(type: string, selectedActivator: number | string | null){
    try{
      this.orderFormGroup.controls['startDateControl'].removeValidators(Validators.required);
      this.orderFormGroup.controls['startDateControl'].setValue(null);
      this.orderFormGroup.controls['startDateControl'].disable();
  
      this.orderFormGroup.controls['startHourControl'].removeValidators(Validators.required);
      this.orderFormGroup.controls['startHourControl'].setValue('');
      this.disabledStartHour = true;
  
      this.orderFormGroup.controls['endDateControl'].removeValidators(Validators.required);
      this.orderFormGroup.controls['endDateControl'].setValue(null);
      this.orderFormGroup.controls['endDateControl'].disable();
  
      this.orderFormGroup.controls['endHourControl'].removeValidators(Validators.required);
      this.orderFormGroup.controls['endHourControl'].setValue('');
      this.disabledEndHour = true;

      this.orderFormGroup.controls['activatorControl'].setValue('');
      this.loadingActivators = true;

      let typeStr = '';
      if(type == 'CA'){
        typeStr = 'Calendario';
      }else if(type == 'SI'){
        typeStr = 'Síntoma';
      }else if(type == 'ME'){
        typeStr = 'Medida';
      }else if(type == 'VA'){
        typeStr = 'Valor';
      }
      
      let idUser = localStorage.getItem('idusuario')!;
      let activators: ActivatorsByTypeResponse = await lastValueFrom(this._countersActivatorsService.getActivatorsByType(
        typeStr, 
        idUser, 
        1
      ));

      if(activators.error){
        this.orderFormGroup.controls['activatorTypeControl'].setValue('');
        this.orderFormGroup.controls['activatorControl'].setValue(0);
        this._resourcesService.openSnackBar(activators.msg);
      }else{
        let activatorsArr: ActivatorByType[] = [];
        let idActivatorSelected: string | number | null = null;
        for(const activator of activators.response){
          activator.IDACTIVADOR = await this._encService.decrypt(activator.IDACTIVADOR as string);

          let priorityFilt: PriorityInterface | null = null;
          for(const priority of this.orderPriorities){
            let valueDec = await this._encService.decrypt(priority.value);
            let activatorPriorityDec = await this._encService.decrypt(activator.PRIORIDAD);
            if(valueDec == activatorPriorityDec){
              priorityFilt = priority;
            }
          }

          if(priorityFilt != null){
            activator.PRIORIDAD_OBJ = priorityFilt!;
            activatorsArr.push(activator);

            if(selectedActivator != null && activator.IDACTIVADOR == `${selectedActivator}`){
              this.orderFormGroup.controls['activatorControl'].setValue(activator.IDACTIVADOR);
              idActivatorSelected = activator.IDACTIVADOR;
            }
          }
        }
        
        this.orderFormGroup.controls['activatorControl'].enable();
        this.activators = activatorsArr;
        

        if(selectedActivator != null){
          this.activatorChange(idActivatorSelected!, type);
        }
      }

      this.loadingActivators = false;
    }catch(error: any){
      this.orderFormGroup.controls['activatorTypeControl'].setValue('');
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (7).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (8).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  private async _getToolsAndSpare () {
    try{
      const USER: string = this._resourcesService.getUser();
      const LINE: number = this._resourcesService.getLineNumber();

      let responseData: ResponseDataGetToolsAndSpare = await lastValueFrom(this._inventoryManagementService.getToolsAndSpare(USER, LINE));

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

      if(this.hasError){
        this.isLoading = false;
      }else{
        let selectedResources: any[] = [];
        if(this.workOrder != null){
          let resourcesArr = JSON.parse(this.workOrder.RECURSOS);
          for(const item of resourcesArr){
            if(item.ID != 'SH'){
              let idDec = await this._encService.decrypt(item.ID);
              selectedResources.push({ID: idDec, TYPE: item.TYPE, REQ: item.REQ});
            }else{
              if(item.TYPE == 'S'){
                let partsVal = this.orderFormGroup.controls['sparePartsControl'].value;
                partsVal.push('SH');

                this.orderFormGroup.controls['sparePartsControl'].setValue(partsVal);
              }else{
                let toolsVal = this.orderFormGroup.controls['toolsControl'].value;
                toolsVal.push('SH');
    
                this.orderFormGroup.controls['toolsControl'].setValue(toolsVal);
              }
            }
          }
        }

        let toolsArr: ToolsAndSpare[] = [];
        for(const tool of responseData.response.HERRAMIENTAS){
          let idToolDec = await this._encService.decrypt(tool.ID);
          let selectedFilter = selectedResources.filter(item => item.ID == idToolDec && item.TYPE == 'T');

          if(selectedFilter.length > 0){
            let toolsVal = this.orderFormGroup.controls['toolsControl'].value;
            toolsVal.push(tool.ID);

            this.orderFormGroup.controls['toolsControl'].setValue(toolsVal);
            this.toolsConf[tool.ID] = selectedFilter[0].REQ;
          }

          toolsArr.push(tool);
        }

        let sparePartsArr: ToolsAndSpare[] = [];
        for(const part of responseData.response.REFACCIONES){
          let idPartDec = await this._encService.decrypt(part.ID);
          let selectedFilter = selectedResources.filter(item => item.ID == idPartDec && item.TYPE == 'S');

          if(selectedFilter.length > 0){
            let partsVal = this.orderFormGroup.controls['sparePartsControl'].value;
            partsVal.push(part.ID);

            this.orderFormGroup.controls['sparePartsControl'].setValue(partsVal);
            this.partsConf[part.ID] = selectedFilter[0].REQ;
          }

          sparePartsArr.push(part);
        }

        this.tools = toolsArr;
        this.spareParts = sparePartsArr;
        this.getSpecialties();
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (9).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (10).';
      }else{
        this.errorStr = error.error.msg;
      }
      
      this.hasError = true;
      this.isLoading = false;
    }
  }

  async activatorChange(value: string | number, type: string){
    this.orderFormGroup.controls['startDateControl'].removeValidators(Validators.required);
    this.orderFormGroup.controls['startDateControl'].setValue(null);
    this.orderFormGroup.controls['startDateControl'].disable();

    this.orderFormGroup.controls['startHourControl'].removeValidators(Validators.required);
    this.orderFormGroup.controls['startHourControl'].setValue('');
    this.disabledStartHour = true;

    this.orderFormGroup.controls['endDateControl'].removeValidators(Validators.required);
    this.orderFormGroup.controls['endDateControl'].setValue(null);
    this.orderFormGroup.controls['endDateControl'].disable();

    this.orderFormGroup.controls['endHourControl'].removeValidators(Validators.required);
    this.orderFormGroup.controls['endHourControl'].setValue('');
    this.disabledEndHour = true;

    if(value == 'CAN'){
      let dialogRef = this._dialog.open(ActivatorDialogComponent, {
        width: '640px',
        maxWidth: '640px',
        data: {
          activatorType: type,
        }
      });

      dialogRef.afterClosed().subscribe(res => {
        if(res == '' || res == undefined ||  res == null){
          this.orderFormGroup.controls['activatorControl'].setValue(0);
        }else{
          this.getActivatorsByType(type, res);
        }
      });
    }else if(this.workOrder != null){
      let idOrderActivatorDec = await this._encService.decrypt(this.workOrder.ACTIVADOR!);
      let activatorFilt = this.activators.filter(item => item.IDACTIVADOR == idOrderActivatorDec);

      if(activatorFilt.length > 0){
        let activator = activatorFilt[0];
        if(activator.TIPOACTIVACION == 'Medida' || activator.TIPOACTIVACION == 'Valor'){
          this.orderFormGroup.controls['startDateControl'].addValidators(Validators.required);
          this.orderFormGroup.controls['startDateControl'].enable();
          this.orderFormGroup.controls['startHourControl'].addValidators(Validators.required);
          this.orderFormGroup.controls['endDateControl'].enable();
          this.disabledStartHour = false;
          this.disabledEndHour = false;
        }
      }
    }else if(type == 'ME' || type == 'VA'){
      this.orderFormGroup.controls['startDateControl'].addValidators(Validators.required);
      this.orderFormGroup.controls['startDateControl'].enable();
      this.orderFormGroup.controls['startHourControl'].addValidators(Validators.required);
      this.orderFormGroup.controls['endDateControl'].enable();
      this.disabledStartHour = false;
      this.disabledEndHour = false;
    }

    this.getActivatorConfigStr(value, type);
  }

  async getSpecialties(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let specialties: SpecialtiesListResponse = await lastValueFrom(this._interventionService.getSpecialties(idUser, 1));

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

      if(!this.hasError){
        let specialtiesSelected: string[] = [];
        if(this.workOrder != null){
          let staffArr: any[] = JSON.parse(this.workOrder.OPERARIOS);
          for(const item of staffArr){
            let idDec = await this._encService.decrypt(item.ID);
            specialtiesSelected.push(idDec);
          }
        }

        let specialtiesArr: SpecialtiesListItem[] = [];
        for(const specialty of specialties.response){
          let codeDec = await this._encService.decrypt(specialty.CODIGO_ESPECIALIDAD);
          specialty.NOMBRE_ESPECIALIDAD = `${specialty.NOMBRE_ESPECIALIDAD} (${codeDec})`;
          
          if(specialty.ESTADO == 'Activo'){
            specialtiesArr.push(specialty);

            let specialtiesVal = this.orderFormGroup.controls['staffControl'].value;
            if(specialtiesSelected.includes(codeDec)){
              specialtiesVal.push(specialty.CODIGO_ESPECIALIDAD);
            }
          }
        }

        this.specialties = specialtiesArr;
      }

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

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

  getActivatorConfigStr(value: string | number, type: string){
    if(this.orderFormGroup.controls['activatorControl'].value == 'CAN'){
      return;
    }
    
    let activatorFilt = this.activators.filter(item => item.IDACTIVADOR == value);
    if(activatorFilt.length > 0){
      let activator = activatorFilt[0];
      let conditionsObj = JSON.parse(activator.CONDICIONES);
      let configStr = "";

      if(type == 'CA' || type == 'SI'){
        let startDate = new Date(conditionsObj.startDate);
        let startHour = this._functionsService.convertFullHourToHumanHour(conditionsObj.startHour);

        switch(conditionsObj.repeat){
          case "NR": 
            this.orderFormGroup.controls['startDateControl'].setValue(startDate);
            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
            
            configStr += "Esta orden no se repite"; 
          break;
          case "AN":
            configStr += `Esta orden se repite anualmente el día ${startDate.getDate()} de ${this.MONTHS[startDate.getMonth()]}`;
  
            this.orderFormGroup.controls['startDateControl'].setValue(startDate);
            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
          break;
          case "ME":
            configStr += `Esta orden se repite mensualmente los días ${startDate.getDate()}`;
  
            this.orderFormGroup.controls['startDateControl'].setValue(startDate);
            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
          break;
          case "SE":
            configStr += `Esta orden se repite semanalmente los días ${this.dayNames[startDate.getDay()]}`;
  
            this.orderFormGroup.controls['startDateControl'].setValue(startDate);
            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
          break;
          case "TD":
            configStr += `Esta ordense repite todos los días desde el ${startDate.getDate()} de ${this.MONTHS[startDate.getMonth()]} del ${startDate.getFullYear()}`;
  
            this.orderFormGroup.controls['startDateControl'].setValue(startDate);
            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
          break;
          case "PE":
            let customRepeat = JSON.parse(conditionsObj.customRepeat);
            let repeatEvery = customRepeat.repeatEvery.split('|');

            switch(repeatEvery[1]){
              case "0":
                let intervalA = parseInt(repeatEvery[0]);
                if(intervalA > 1){
                  configStr += `Esta orden se repite cada ${intervalA} días `;
                }else{
                  configStr += `Esta orden se repite cada día `;
                }
              break;
              case "1":
                let intervalB = parseInt(repeatEvery[0]);
                if(intervalB > 1){
                  configStr += `Esta orden se repite cada ${intervalB} semanas `;
                }else{
                  configStr += `Esta orden se repite cada semana `;
                }
                
                let repeatOnVals = Object.values(customRepeat.repeatOn);
                let ind = 0;
                let cont = 0;
                let daysStr = "";
  
                repeatOnVals.forEach(val => {
                  if(val){
                    daysStr += `${this.dayNames[ind]}, `;
                    cont++;
                  }
  
                  ind++;
                });
  
                daysStr = daysStr.substring(0, daysStr.length - 2);
                if(cont > 1){
                  configStr += `los días ${daysStr} `;
                }else{
                  configStr += `el día ${daysStr} `;
                }
              break;
              case "2":
                let intervalC = parseInt(repeatEvery[0]);
                if(intervalC > 1){
                  configStr += `Esta orden se repite cada ${intervalC} meses `;
                }else{
                  configStr += `Esta orden se repite cada mes `;
                }
              break;
              case "3":
                let intervalD = parseInt(repeatEvery[0]);
                if(intervalD > 1){
                  configStr += `Esta orden se repite cada ${intervalD} años `;
                }else{
                  configStr += `Esta orden se repite cada año `;
                }
              break;
            }

            configStr += `a partir del ${startDate.getDate()} de ${this.MONTHS[startDate.getMonth()]} del ${startDate.getFullYear()}, `;
            let endsAt = customRepeat.endsAt.split('|');

            if(endsAt[0] == 'N'){
              configStr += `sin parámetros de finalización.`;
            }else if(endsAt[0] == 'O'){
              let dateArr = endsAt[1].split('-');
              let dateObj = new Date(parseInt(dateArr[0]), parseInt(dateArr[1]), parseInt(dateArr[2]));
              configStr += `finaliza el día ${dateObj.getDate()} de ${this.MONTHS[dateObj.getMonth()]} del ${dateObj.getFullYear()}.`;
            
              this.orderFormGroup.controls['endDateControl'].setValue(dateObj);
              this.orderFormGroup.controls['endHourControl'].addValidators(Validators.required);
              this.disabledEndHour = false;
            }else if(endsAt[0] == 'A'){
              configStr += `finaliza después de ${endsAt[2]} repetici${parseInt(endsAt[2]) > 1 ? 'ones' : 'ón'}.`;
            }
          
            this.orderFormGroup.controls['startDateControl'].setValue(startDate);
            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
          break;
        }
      }else{
        configStr += `Magnitud medida: ${conditionsObj.magnitude}. `;
        configStr += `Unidad configurada: ${conditionsObj.unit}. `;

        if(type == 'ME'){
          configStr += `Valor mínimo: ${this.formatNumbers(conditionsObj.minValue)}. `;
          configStr += `Valor máximo: ${this.formatNumbers(conditionsObj.maxValue)}`;
        }else{
          configStr += `Valor límite: ${this.formatNumbers(conditionsObj.limitValue)}. `;

          if(conditionsObj.comparison == 'AC'){
            configStr += "Comparación con el valor acumulado.";
          }else{
            configStr += "Comparación con el último valor reportado.";
          }
        }
      }
      this.activatorConfigStr = configStr;
    }
  }

  initTables(){
    setTimeout(() => {
      let equipment = this.orderFormGroup.controls['equipmentControl'].value;
      if(equipment != null && equipment != undefined && equipment != ''){
        this.changeEquipmentTable(equipment);
      }

      let specialties = this.orderFormGroup.controls['staffControl'].value;
      this.updateSpecialty(specialties);
      setTimeout(async () => {
        if(this.workOrder != null){
          let specialtiesArr = JSON.parse(this.workOrder.OPERARIOS);
          for(const specialty of specialtiesArr){
            specialty.ID = await this._encService.decrypt(specialty.ID);
          }

          for(const item of specialties){
            let input = this._document.getElementById(`cant-req-${item}`) as HTMLInputElement;
            let itemDec = await this._encService.decrypt(item);
            let specialtyFilt = specialtiesArr.filter((item1: any) => item1.ID == itemDec);

            if(specialtyFilt.length > 0){
              input.value = specialtyFilt[0].CANT;
            }else{
              input.value = '1';
            }
          }
        }
      }, 100);
      
      let toolsVal = this.orderFormGroup.controls['toolsControl'].value;
      let partsVal = this.orderFormGroup.controls['sparePartsControl'].value;

      this.toolsChange(toolsVal, partsVal);
      setTimeout(() => {
        let toolsKeys = Object.keys(this.toolsConf);
        for(const key of toolsKeys){
          if(key != 'SH'){
            let input = this._document.getElementById(`cant-req-${key}`) as HTMLInputElement;
            input.value = this.toolsConf[key];
          }
        }

        let partsKeys = Object.keys(this.partsConf);
        for(const key of partsKeys){
          if(key != 'SH'){
            let input = this._document.getElementById(`cant-req-${key}`) as HTMLInputElement;
            input.value = this.partsConf[key];
          }
        }
      }, 100);
    }, 100);
  }

  formatNumbers(number: string | number): string{
    let numberStr = `${number}`;
    let numberArr = numberStr.split('').reverse();

    let num = "";
    for(let i = 0; i < numberArr.length - 1; i++){
      let res = i % 3;
      if(res == 2){
        num += `${numberArr[i]},`;
      }else{
        num += `${numberArr[i]}`;
      }
    }

    num += `${numberArr[numberArr.length - 1]}`;
    let numFn = num.split('').reverse().join('');
    
    return numFn;
  }

  async changeEquipmentTable(equipmentCode: string){
    try{
      let equipmentArr = equipmentCode.split(' - ');
      if(equipmentArr.length == 3){
        let idUser = localStorage.getItem('idusuario')!;
        let equipmentCodeEnc = await this._encService.encrypt(equipmentArr[0]);
        let equipment: EquipmentDetailsResponse = await lastValueFrom(this._equipmentsService.equipmentConsultOnly(equipmentCodeEnc, idUser, 1));

        if(equipment.error){
          this._resourcesService.openSnackBar(equipment.msg);
        }else{
          let codeDec = await this._encService.decrypt(equipment.response.CODIGO);
          let equipmentTypeDec = await this._encService.decrypt(equipment.response.TIPO_EQUIPAMIENTO);
          equipment.response.TIPO_EQUIPAMIENTO = `${codeDec} - ${equipmentTypeDec}`;

          let modelDec = await this._encService.decrypt(equipment.response.MODELO);
          let idDec = await this._encService.decrypt(equipment.response.ID_EQUIPAMIENTO);
          equipment.response.MODELO = `${modelDec} (${idDec})`;
      
          this.dataSource = new MatTableDataSource([equipment.response]);
        }
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (13).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (14).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  updateSpecialty(specialties: string[]){
    let specialtiesSel: SpecialtiesListItem[] = [];
    for(const idSpecialty of specialties){
      let specialtyFilt = this.specialties.filter(item => item.CODIGO_ESPECIALIDAD == idSpecialty);
      if(specialtyFilt.length > 0){
        specialtiesSel.push(specialtyFilt[0]);
      }
    }

    this.specialtiesDataSource = new MatTableDataSource(specialtiesSel);
  }

  toolsChange(toolsValue: string[], partsValue: string[]){
    this.toolsDataSource = new MatTableDataSource();
    this.toolsParts = [];

    let toolsAux: ToolsAndSpare[] = [];
    if(toolsValue != undefined && !toolsValue.includes('SH')){
      toolsValue.forEach(item => {
        let tool = this.tools.filter(item2 => item.toString() == item2.ID.toString())[0];
        toolsAux.push(tool);
      });
    }else if(toolsValue.includes('SH')){
      this.orderFormGroup.controls['toolsControl'].setValue(['SH']);
    }

    let partsAux: ToolsAndSpare[] = [];
    if(partsValue != undefined && !partsValue.includes('SH')){
      partsValue.forEach(item => {
        let part = this.spareParts.filter(item2 => item.toString() == item2.ID.toString())[0];
        partsAux.push(part);
      });
    }else if(partsValue.includes('SH')){
      this.orderFormGroup.controls['sparePartsControl'].setValue(['SH']);
    }

    toolsAux.forEach(item => this.toolsParts.push(item));
    partsAux.forEach(item => this.toolsParts.push(item));

    this.toolsDataSource = new MatTableDataSource(this.toolsParts);
  }

  onResize():void{
    this.activCols = window.innerWidth > 840 ? 2 : 1;
    this.datesCols = window.innerWidth > 1164 ? 4 : window.innerWidth > 840 ? 2 : 1;
    this.timesCols = window.innerWidth > 1164 ? 3 : window.innerWidth > 840 ? 2 : 1;
    this.toolsCols = window.innerWidth > 840 ? 2 : 1;
    this.screenSize = window.innerWidth;
  }

  openTimePicker(type: string){
    let time = type == 'start' ? this.orderFormGroup.controls['startHourControl'].value : this.orderFormGroup.controls['endHourControl'].value;
    let dialogRef = this._dialog.open(TimePickerComponent, {
      data: {
        time: time,
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        if(type == 'start'){
          this.orderFormGroup.controls['startHourControl'].setValue(res);
        }else{
          this.orderFormGroup.controls['endHourControl'].setValue(res);
        }
        
        this.verifyDateTime(type);
      }
    });
  }

  openArborescenceSearch(){
    let dialogRef = this._dialog.open(GraphicEquipmentSearchComponent, {
      disableClose: true,
      width: '720px',
      maxWidth: '720px',
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        this.orderFormGroup.controls['equipmentControl'].setValue(res);
        this.changeEquipmentTable(res);
      }
    });
  }

  async openEquipmentDetails(equipmentCode: string){
    this._dialog.open(EquipmentDetailsDialogComponent, {
      width: '480px',
      maxWidth: '480px',
      data: {
        code: equipmentCode,
      }
    });
  }

  async openEquipmentArborescence(selectedEquipment: string){
    let codeDec = await this._encService.decrypt(selectedEquipment);
    let codeArr = codeDec.split('_');

    if(codeArr.length == 2){
      let pbsArr = codeArr[1].split('.');
      if(pbsArr.length > 3){
        let familyEnc = await this._encService.encrypt(pbsArr[0]);
        let subFamilyEnc = await this._encService.encrypt(pbsArr[1]);
        let arborescence: string[] = [];

        for(let i = 3; i < pbsArr.length; i++){
          let equipmentCode = pbsArr[i];
          let parentIndex = i - 4;

          if(parentIndex >= 0){
            let parent = arborescence[parentIndex];
            let fullCode = `${parent}.${equipmentCode}`;
            arborescence.push(fullCode);
          }else{
            let fullCode = `${codeArr[0]}_${pbsArr[0]}.${pbsArr[1]}.${pbsArr[2]}.${equipmentCode}`;
            arborescence.push(fullCode);
          }
        }

        let arborescenceArr: string[] = [];
        for(const item of arborescence){
          let itemEnc = await this._encService.encrypt(item);
          arborescenceArr.push(itemEnc);
        }

        let arborescenceStr = JSON.stringify(arborescenceArr);
        let arborescenceEnc = window.btoa(arborescenceStr);

        let url = this._router.createUrlTree(['sam/GEEQ'], {
          queryParams: {
            family: familyEnc,
            subfamily: subFamilyEnc,
            arborescence: arborescenceEnc
          }
        });

        if(window.location.href.includes('#')){
          let locationArr = window.location.href.split('#');
          window.open(`${locationArr[0]}#${url.toString()}`);
        }
      }
    }
  }

  async openEquipmentDocuments(equipmentCode: string){
    try{
      this._resourcesService.openSnackBar('Obteniendo lista de documentos...');

      let idUser = localStorage.getItem('idusuario')!;
      let equipment: EquipmentDetailsResponse = await lastValueFrom(this._equipmentsService.equipmentConsultOnly(equipmentCode, idUser, 1));

      if(equipment.error){
        this._resourcesService.openSnackBar(equipment.msg);
      }else{
        equipment.response.CODIGO = await this._encService.decrypt(equipment.response.CODIGO);
        equipment.response.TIPO_EQUIPAMIENTO = await this._encService.decrypt(equipment.response.TIPO_EQUIPAMIENTO);
        equipment.response.MODELO = await this._encService.decrypt(equipment.response.MODELO);
        equipment.response.ID_EQUIPAMIENTO = await this._encService.decrypt(equipment.response.ID_EQUIPAMIENTO);

        this._dialog.open(EquipmentDocumentsComponent, {
          width: '520px',
          maxWidth: '520px',
          data: {
            equipment: `${equipment.response.CODIGO} - ${equipment.response.TIPO_EQUIPAMIENTO} - ${equipment.response.MODELO} (${equipment.response.ID_EQUIPAMIENTO})`,
            documents: JSON.parse(equipment.response.DOCUMENTOS as string)
          }
        });
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (15).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (16).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  addStep(type: string, id: string | null){
    let ins = this.instructions.filter(item => item.ID == id);
    let startDate = this.orderFormGroup.controls['startDateControl'].value;
    let endDate = this.orderFormGroup.controls['endDateControl'].value;
    
    let dialogRef = this._dialog.open(NewInstructionComponent, {
      width: '560px',
      maxWidth: '560px',
      data: {
        action: type,
        instruction: ins.length > 0 ? ins[0] : null,
        startDate: startDate,
        endDate: endDate,
      }
    }); 

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        let instructionObj = JSON.parse(res);
        let now = (new Date()).getTime();

        let orderStartDate = this.orderFormGroup.controls['startDateControl'].value as Date;
        let orderStartYear = orderStartDate.getFullYear();
        let orderStartMonth = orderStartDate.getMonth() + 1;
        let orderStartDay = orderStartDate.getDate();
        let orderStartTime = this.orderFormGroup.controls['startHourControl'].value;
        let orderStartDateTime = new Date(`${orderStartYear}-${orderStartMonth}-${orderStartDay} ${orderStartTime}`);
        let orderStartTimestamp = orderStartDateTime.getTime();
        
        let instructionStartDate = new Date(instructionObj.startDate);
        let instructionStartYear = instructionStartDate.getFullYear();
        let instructionStartMonth = instructionStartDate.getMonth() + 1;
        let instructionStartDay = instructionStartDate.getDate();
        let instructionStartTime = instructionObj.startHour;
        let instructionStartDateTime = new Date(`${instructionStartYear}-${instructionStartMonth}-${instructionStartDay} ${instructionStartTime}`);
        let instructionStartTimestamp = instructionStartDateTime.getTime();

        if(instructionStartTimestamp < orderStartTimestamp){
          this._resourcesService.openSnackBar('La fecha de inicio de la instrucción no puede ser menor a la fecha de inicio de la orden de trabajo.');
          return;
        }
        
        let instructionEndDate = new Date(instructionObj.endDate);
        let instructionEndYear = instructionEndDate.getFullYear();
        let instructionEndMonth = instructionEndDate.getMonth() + 1;
        let instructionEndDay = instructionEndDate.getDate();
        let instructionEndTime = instructionObj.endHour;
        let instructionEndDateTime = new Date(`${instructionEndYear}-${instructionEndMonth}-${instructionEndDay} ${instructionEndTime}`);
        let instructionEndTimestamp = instructionEndDateTime.getTime();

        let orderEndDate = this.orderFormGroup.controls['endDateControl'].value as Date;
        if(orderEndDate != null && orderEndDate != undefined){
          let orderEndYear = orderEndDate.getFullYear();
          let orderEndMonth = orderEndDate.getMonth() + 1;
          let orderEndDay = orderEndDate.getDate();
          let orderEndTime = this.orderFormGroup.controls['endHourControl'].value;
          let orderEndDateTime = new Date(`${orderEndYear}-${orderEndMonth}-${orderEndDay} ${orderEndTime}`);
          let orderEndTimestamp = orderEndDateTime.getTime();

          if(instructionEndTimestamp > orderEndTimestamp){
            this._resourcesService.openSnackBar('La fecha del término de la instrucción no puede ser mayor a la fecha del término de la orden de trabajo.');
            return;
          }
        }

        let difference = instructionEndTimestamp - instructionStartTimestamp;
        let diffInSeconds = difference / 1000;
        let diffInMinutes = diffInSeconds / 60;
        let diffInHours = diffInMinutes / 60;

        if(type == 'new'){
          let instruction: Instruction = {
            ID: `${now}`,
            INSTRUCCION: instructionObj.instruction,
            DURACION: parseFloat(diffInHours.toFixed(2)),
            INICIO: `${instructionStartYear}-${instructionStartMonth}-${instructionStartDay} ${instructionStartTime}`,
            FIN: `${instructionEndYear}-${instructionEndMonth}-${instructionEndDay} ${instructionEndTime}`,
            COSTO: 0,
            ESPECIALIDADES: '',
            ISFROMFILE: false,
            IDFILE: ''
          };

          this.instructions.push(instruction);
        }else{
          ins[0].INSTRUCCION = instructionObj.instruction;
          ins[0].DURACION = parseFloat(diffInHours.toFixed(2));
          ins[0].INICIO = `${instructionStartYear}-${instructionStartMonth}-${instructionStartDay} ${instructionStartTime}`;
          ins[0].FIN = `${instructionEndYear}-${instructionEndMonth}-${instructionEndDay} ${instructionEndTime}`;
          ins[0].ESPECIALIDADES = instructionObj.specialties;
        }

        this.calcTotalDuration();
      }
    });
  }

  calcTotalDuration(){
    try{
      let minDate: Date | null = null;
      let maxDate: Date | null = null;
  
      this.instructions.forEach(ins => {
        if(minDate == null){
          minDate = new Date(ins.INICIO);
        }else{
          let startDate = new Date(ins.INICIO);
          let minTimestamp = minDate.getTime();
          let startTimestamp = startDate.getTime();
  
          if(startTimestamp < minTimestamp){
            minDate = startDate;
          }
        }
  
        if(maxDate == null){
          maxDate = new Date(ins.FIN);
        }else{
          let endDate = new Date(ins.FIN);
          let maxTimestamp = maxDate.getTime();
          let endTimestamp = endDate.getTime();
  
          if(endTimestamp > maxTimestamp){
            maxDate = endDate;
          }
        }
      });

      if(minDate != null && maxDate != null){
        let minTimestamp = (minDate as Date).getTime();
        let maxTimestamp = (maxDate as Date).getTime();
    
        let difference = maxTimestamp - minTimestamp;
        let seconds = difference / 1000;
        let minutes = seconds / 60;
        let hours = minutes / 60;
        
        this.orderFormGroup.controls['totalTimeControl'].setValue(`${hours.toFixed(2)}`);
        let inmTime = this.orderFormGroup.controls['inmTimeControl'].value;
        let inmTimeNum = parseFloat(inmTime);
        
        if(!isNaN(inmTimeNum)){
          if(inmTimeNum > hours){
            this._resourcesService.openSnackBar('El valor del tiempo de inmovilización no puede ser mayor al tiempo total.');
            this.orderFormGroup.controls['inmTimeControl'].setValue('');
          }
        }
      }
    }catch(_: any){ }
  }

  drop(event: CdkDragDrop<Instruction[]>){
    moveItemInArray(this.instructions, event.previousIndex, event.currentIndex);
  }

  getRange(startDateTimeStr: string, endDateTimeStr: string): string{
    let startDateTime = new Date(startDateTimeStr);
    let startDay = startDateTime.getDate() < 10 ? `0${startDateTime.getDate()}` : `${startDateTime.getDate()}`;
    let startMonth = startDateTime.getMonth() + 1 < 10 ? `0${startDateTime.getMonth() + 1}` : `${startDateTime.getMonth() + 1}`;
    let startYear = `${startDateTime.getFullYear()}`.substring(2);
    let startHourInt = startDateTime.getHours();
    let startPeriod = startHourInt < 12 ? 'AM' : 'PM';
    startHourInt = startHourInt > 12 ? startHourInt - 12 : startHourInt;
    let startHour = startHourInt < 10 ? `0${startHourInt}` : `${startHourInt}`;
    let startMinutes = startDateTime.getMinutes() < 10 ? `0${startDateTime.getMinutes()}` : `${startDateTime.getMinutes()}`;
    let startDateTimeRet = `${startDay}/${startMonth}/${startYear} ${startHour}:${startMinutes} ${startPeriod}`;

    let endDateTime = new Date(endDateTimeStr);
    let endDay = endDateTime.getDate() < 10 ? `0${endDateTime.getDate()}` : `${endDateTime.getDate()}`;
    let endMonth = endDateTime.getMonth() + 1 < 10 ? `0${endDateTime.getMonth() + 1}` : `${endDateTime.getMonth() + 1}`;
    let endYear = `${endDateTime.getFullYear()}`.substring(2);
    let endHourInt = endDateTime.getHours();
    let endPeriod = endHourInt < 12 ? 'AM' : 'PM';
    endHourInt = endHourInt > 12 ? endHourInt - 12 : endHourInt;
    let endHour = endHourInt < 10 ? `0${endHourInt}` : `${endHourInt}`;
    let endMinutes = endDateTime.getMinutes() < 10 ? `0${endDateTime.getMinutes()}` : `${endDateTime.getMinutes()}`;
    let endDateTimeRet = `${endDay}/${endMonth}/${endYear} ${endHour}:${endMinutes} ${endPeriod}`;
    
    return `${startDateTimeRet} - ${endDateTimeRet}`;
  }

  deleteStep(id: string, ind: number){
    let step = this.instructions.filter(item => item.ID == id)[0];
    let dialogRef = this._dialog.open(AlertComponent, {
      disableClose: true,
      width: '480px',
      maxWidth: '480px',
      data: {
        title: 'Confirmar acción',
        icon: 'help',
        description: `¿Está seguro de querer eliminar la instrucción "${ind}.- ${step.INSTRUCCION}"?`,
        description2: 'Esta acción no se puede deshacer.'
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res == true){
        let instructionsAux: Instruction[] = [];
    
        this.instructions.forEach(ins => {
          if(ins.ID != id){
            instructionsAux.push(ins);
          }
        });
    
        this.instructions = instructionsAux;
        this.calcTotalDuration();
      }
    });
  }

  changeReq(action: string, id: string){
    let input = this._document.getElementById(`cant-req-${id}`) as HTMLInputElement;
    let val = parseInt(input.value);
    if(action == 'add'){
      val++;
      input.value = `${val}`;
    }else if(val > 1){
      val--;
      input.value = `${val}`;
    }else{
      input.value = '1';
    }
  }

  validateCant(value: string, id: string){
    let input = this._document.getElementById(`cant-req-${id}`) as HTMLInputElement;
    if(value == ""){
      input.value = '1';
    }else if(value == '0'){
      input.value = '1';
    }else{
      let validString = "";
      let valueArr = value.split('');
      let numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];

      valueArr.forEach(char => {
        if(numbers.includes(char)){
          validString += char;
        }
      });

      input.value = validString;
    }
  }

  verifyInmTime(val: string){
    let totalTimeVal = this.orderFormGroup.controls['totalTimeControl'].value;
    this.orderFormGroup.controls['inmTimeControl'].markAsTouched();
    let totalTimeNum = parseFloat(totalTimeVal);
    let valNum = parseFloat(val);

    if(!isNaN(totalTimeNum) && !isNaN(valNum)){
      if(valNum > totalTimeNum){
        this._resourcesService.openSnackBar('El valor del tiempo de inmovilización no puede ser mayor al tiempo total.');
        this.orderFormGroup.controls['inmTimeControl'].setValue('');
      }
    }
  }
  
  verifyLength(value: string, length: number){
    let str = value.length > length ? value.substring(0, length) : value;
    this.orderFormGroup.controls['clasificationControl'].markAsTouched();
    this.orderFormGroup.controls['clasificationControl'].setValue(str);
  }

  isPositive(calcDisp: string, id: string): boolean{
    let input = this._document.getElementById(`cant-req-${id}`) as HTMLInputElement;
    let cd = parseInt(calcDisp);
    let cr = parseInt(input.value);
    
    return cd - cr > 0;
  }

  calcRest(calcDisp: string, id: string): string{
    let input = this._document.getElementById(`cant-req-${id}`) as HTMLInputElement;
    let cd = parseInt(calcDisp);
    let cr = parseInt(input.value);
    
    return `${cd - cr}`;
  }

  openFileUploader(){
    this.uploader?.nativeElement.click();
  }

  searchExistingFile(){
    let existingFiles = this.attached.filter(item => item.type == 'Existente');
    
    let dialogRef = this._dialog.open(SearchFileDialogComponent, {
      width: '1024px',
      maxWidth: '1024px',
      data: {
        files: existingFiles,
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ""){
        let files: FindedFile[] = JSON.parse(res);
        files.forEach(async (item) => {
          let existingFiles: TempFileInfo[] = [];
          for(const file of this.attached){
            let idDec = await this._encService.decrypt(file.id);
            let filt = files.filter(item0 => idDec == `${item0.CODIGO}=${item0.VERSION}=${item.NOMBRE}`);
            if(filt.length > 0){
              existingFiles.push(file)
            }
          }
          
          let idFile = `${item.CODIGO}=${item.VERSION}=${item.NOMBRE}`;
          let fileEnc = await this._encService.encrypt(idFile);
          let file: TempFileInfo = {
            id: fileEnc,
            name: item.NOMBRE,
            size: `${item.TAMANIO}`,
            type: 'Existente'
          };

          if(existingFiles.length < 1){
            this.attached.push(file);
          }
        });
      }
    });
  }

  async deleteFile(id: string, type: string){
    try{
      if(this.deleteFilesDisabled == false){
        this.deleteFilesDisabled = true;
  
        if(type == 'Nuevo'){
          let idUser = localStorage.getItem('idusuario');
  
          await lastValueFrom(this._gdelService.deleteTempFile({
            'id_user': idUser!,
            'id_file': id,
            'linea': 1,
          }));
        }
  
        let instructionsAux: Instruction[] = [];
        this.instructions.forEach(ins => {
          if(!(ins.ISFROMFILE && ins.IDFILE == id)){
            instructionsAux.push(ins);
          }
        });
  
        this.instructions = instructionsAux;
        this.calcTotalDuration();
  
        let attachedAux: TempFileInfo[] = [];
        this.attached.forEach(item => {
          if(item.id != id){
            attachedAux.push(item);
          }
        });
  
        this.deleteFilesDisabled = false;
        this.attached = attachedAux;
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (17).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (18).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  checkFile(event: any){
    let fileTypes = availableFiles;
    let sizes = Object.keys(fileTypes);
    let extensions = Object.values(fileTypes);
    let maxSizeMB = 0;

    let extArr = event.target.files[0].name.split(".").reverse();
    let extStr = extArr[0];

    let i = 0;
    extensions.forEach(ext => {
      let size = parseInt(sizes[i]);

      if(ext.includes(extStr)) maxSizeMB = size;
      i++;
    });

    if(maxSizeMB == 0){
      this._resourcesService.openSnackBar(`Los archivos ${extStr} no están soportados`);
    }else{
      let maxFileSize = 1048576 * maxSizeMB;
      let fileSize = event.target.files[0].size;

      if(fileSize > maxFileSize){
        this._resourcesService.openSnackBar(`El tamaño del archivo supera el límite de ${maxSizeMB} MB`);
      }else{
        let alreadyAttached = false;
        this.attached.forEach(file => {
          alreadyAttached = file.name == event.target.files[0].name && file.size == this.formatBytes(event.target.files[0].size);
        });

        if(alreadyAttached){
          this._resourcesService.openSnackBar("El archivo seleccionado ya fue adjuntado.");
        }else{
          this.isUploading = true;
          this.uploadTmp(event.target.files[0]);
        }
      }
    }
  }

  formatBytes(bytes: number, decimals = 2) {
    if (bytes === 0) return '0 Bytes';

    const k = 1024;
    const dm = decimals < 0 ? 0 : decimals;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

    const i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
  }

  async uploadTmp(fileData: any){
    try{
      let idUser = localStorage.getItem('idusuario');
      let formData = new FormData();

      formData.append('file', fileData);
      formData.append('id_user', idUser!);
      formData.append('linea', "1");

      let response = await lastValueFrom(this._gdelService.uploadTempFile(formData));

      if(response.error){
        this._resourcesService.openSnackBar(response.msg);
      }else{
        let uploadedFile: TempFileInfo = {
          id: response.response.idArchivo,
          name: fileData.name,
          size: this.formatBytes(fileData.size),
          type: 'Nuevo',
          isMaintenancePlan: false,
        };

        this.attached.push(uploadedFile);
      }

      this.isUploading = false;
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (19).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (20).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
      this.isUploading = false;
    }
  }

  openUploadMaintenancePlanDialog(){
    let dialogRef = this._dialog.open(UploadMaintenancePlanComponent, {
      disableClose: true,
      width: '480px',
      maxWidth: '480px',
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ""){
        let resArr = res.split('|');
        let file: TempFileInfo = JSON.parse(resArr[1]);

        file.type = 'Nuevo';
        file.isMaintenancePlan = true;

        this.attached.push(file);
        this.addInstructionFromFile(resArr[0], file.id);
      }
    });
  }

  async addInstructionFromFile(instructionsStr: string, idFile: string){
    let instructionsArr = JSON.parse(instructionsStr);
    this.deleteFilesDisabled = true;

    for(const instruction of instructionsArr){
      let date = new Date();
      let timestamp = date.getTime();

      let instructionObj: Instruction = {
        ID: `${timestamp}`,
        INSTRUCCION: instruction.INSTRUCTION,
        DURACION: instruction.DURATION,
        INICIO: instruction.START,
        FIN: instruction.END,
        COSTO: parseFloat(instruction.COST),
        ESPECIALIDADES: '',
        ISFROMFILE: true,
        IDFILE: idFile,
      };

      this.instructions.push(instructionObj);
      await this.timeout(1);
    }

    this.deleteFilesDisabled = false;
    this.calcTotalDuration();
  }

  async timeout(ms: number): Promise<void>{
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  async saveChanges(){
    try{
      let idUser = localStorage.getItem('idusuario');
      let formData = new FormData();
      let formValue = this.orderFormGroup.getRawValue();

      let description = formValue.descriptionControl == '' ? '-' : formValue.descriptionControl;
      formData.append('description', description);

      let staffStr = '[]';
      if(formValue.staffControl.length > 0){
        let specialtiesArr: any[] = [];
        for(const specialty of formValue.staffControl){
          let input = this._document.getElementById(`cant-req-${specialty}`) as HTMLInputElement;
          let valStr = input.value;
          let valNum = parseInt(valStr) <= 0 ? 1 : parseInt(valStr);

          specialtiesArr.push({
            SPECIALTY: specialty,
            CANT: valNum,
          });
        }

        staffStr = JSON.stringify(specialtiesArr);
      }
      
      formData.append('staff', staffStr);

      let startDate = formValue.startDateControl == null ? '-' : this._functionsService.getFormattedDate(formValue.startDateControl as Date);
      formData.append('start_date', startDate);

      let startHour = formValue.startHourControl == '' ? '-' : this._functionsService.convertHumanHourToFullHour(formValue.startHourControl);
      formData.append('start_hour', startHour);

      let endDate = formValue.endDateControl == null ? '-' : this._functionsService.getFormattedDate(formValue.endDateControl as Date);
      formData.append('end_date', endDate);

      let endHour = formValue.endHourControl == '' ? '-' : this._functionsService.convertHumanHourToFullHour(formValue.endHourControl);
      formData.append('end_hour', endHour);

      let equipment = '-';
      if(formValue.equipmentControl != ''){
        let equipmentArr = formValue.equipmentControl.split(' - ');
        if(equipmentArr.length != 3){
          this._resourcesService.openSnackBar('El formato del equipamiento seleccionado es inválido.');
          return;
        }else{
          equipment = await this._encService.encrypt(equipmentArr[0]);
        }
      }

      formData.append('equipment', equipment);

      let inmTime = formValue.inmTimeControl == '' ? '-' : formValue.inmTimeControl;
      formData.append('inm_time', inmTime);

      let totalTime = formValue.totalTimeControl == '' ? '-' : formValue.totalTimeControl;
      formData.append('total_time', totalTime);
      formData.append('attached', JSON.stringify(this.attached));

      let activatorType = formValue.activatorTypeControl == '' ? '-' : formValue.activatorTypeControl;
      formData.append('activator_type', activatorType);

      let activator = formValue.activatorControl == 0 ? '-' : await this._encService.encrypt(`${formValue.activatorControl}`);
      formData.append('activator', activator);
      formData.append('id_user', idUser!);
      formData.append('linea', '1');
      formData.append('exists', this.isNew ? 'N' : 'S');
      
      if(!this.isNew){
        formData.append('id_order', this.idOrder!);
      }

      let instructions = '[]';
      if(this.instructions.length > 0){
        let instructionsEnc: Instruction[] = [];
        for(const instruction of this.instructions){
          instruction.ID = await this._encService.encrypt(instruction.ID);
          instructionsEnc.push(instruction);
        }

        instructions = JSON.stringify(instructionsEnc);
      }
      
      formData.append('instructions', instructions);

      let classification = formValue.clasificationControl == '' ? '-' : formValue.clasificationControl;
      formData.append('clasification', classification);

      let resourcesConf: any[] = [];
      for(const tool of formValue.toolsControl){
        if(tool == 'SH'){
          resourcesConf.push({
            ID: 'SH',
            REQ: '-',
            TYPE: 'T'
          });
        }else{
          let input = this._document.getElementById(`cant-req-${tool}`) as HTMLInputElement;
          if(input.value == ''){
            resourcesConf.push({
              ID: tool,
              REQ: 0,
              TYPE: 'T'
            });
          }else{
            resourcesConf.push({
              ID: tool,
              REQ: input.value,
              TYPE: 'T'
            });
          }
        }
      }

      for(const sparePart of formValue.sparePartsControl){
        if(sparePart == 'SH'){
          resourcesConf.push({
            ID: 'SH',
            REQ: '-',
            TYPE: 'S'
          });
        }else{
          let input = this._document.getElementById(`cant-req-${sparePart}`) as HTMLInputElement;
          if(input.value == ''){
            resourcesConf.push({
              ID: sparePart,
              REQ: 0,
              TYPE: 'S'
            });
          }else{
            resourcesConf.push({
              ID: sparePart,
              REQ: input.value,
              TYPE: 'S'
            });
          }
        }
      }
      
      formData.append('resources', JSON.stringify(resourcesConf));
      await lastValueFrom(this._prevMaintService.savePresetWorkOrder(formData));

      this._resourcesService.openSnackBar('El borrador se guardó correctamente');
      window.history.back();
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (21).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (22).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async registerWorkOrder(){
    try{
      if(this.orderFormGroup.invalid){
        this._resourcesService.openSnackBar('El formulario no ha sido llenado correctamente.');
        this.orderFormGroup.markAllAsTouched();
      }else{
        let idUser = localStorage.getItem('idusuario');
        let formValue = this.orderFormGroup.getRawValue();
        let formData = new FormData();
        let specialtiesArr: any[] = [];

        for(const specialty of formValue.staffControl){
          let specialtyFilt = this.specialties.filter(item => item.CODIGO_ESPECIALIDAD == specialty);
          if(specialtyFilt.length > 0){
            let input = this._document.getElementById(`cant-req-${specialty}`) as HTMLInputElement;
            if(input == null){
              this._resourcesService.openSnackBar(`No se pudo encontrar la configuración de la especialidad ${specialtyFilt[0].NOMBRE_ESPECIALIDAD}.`);
              return;
            }

            let valStr = input.value;
            let valNum = parseInt(valStr);
            if(valNum <= 0){
              this._resourcesService.openSnackBar(`La cantidad de operarios para la especialidad ${specialtyFilt[0].NOMBRE_ESPECIALIDAD} no puede ser igual o menor a cero.`);
              return;
            }

            specialtiesArr.push({
              SPECIALTY: specialty,
              CANT: valNum,
            });
          }
        }

        let staffStr = JSON.stringify(specialtiesArr);
        formData.append('staff', staffStr);
        formData.append('description', formValue.descriptionControl!);

        let startDate = this._functionsService.getFormattedDate(formValue.startDateControl as Date);
        formData.append('start_date', startDate);

        let startHour = this._functionsService.convertHumanHourToFullHour(formValue.startHourControl);
        formData.append('start_hour', startHour);
        
        let endDate = formValue.endDateControl == null ? null : this._functionsService.getFormattedDate(formValue.endDateControl as Date);
        if(endDate != null){
          let endHour = this._functionsService.convertHumanHourToFullHour(formValue.endHourControl);

          formData.append('end_date', endDate);
          formData.append('end_hour', endHour);
        }
        
        let equipmentArr = formValue.equipmentControl.split(' - ');
        if(equipmentArr.length != 3){
          this._resourcesService.openSnackBar('El formato del equipamiento seleccionado es inválido.');
          return;
        }
        
        let equipment = await this._encService.encrypt(equipmentArr[0]);
        formData.append('equipment', equipment);
        formData.append('inm_time', formValue.inmTimeControl!);
        formData.append('total_time', formValue.totalTimeControl!);
        formData.append('attached', JSON.stringify(this.attached));
        
        let activatorsEnc = await this._encService.encrypt(`${formValue.activatorControl!}`);
        formData.append('activator', activatorsEnc);
        formData.append('id_user', idUser!);
        formData.append('linea', '1');
        formData.append('exists', this.isNew ? 'N' : 'S');

        if(!this.isNew){
          formData.append('id_order', this.idOrder!);
        }
            
        if(this.instructions.length == 0){
          this._resourcesService.openSnackBar('La orden de be contener al menos una instrucción.');
          return;
        }

        let instructionsEnc: Instruction[] = [];
        for(const instruction of this.instructions){
          instruction.ID = await this._encService.encrypt(instruction.ID);
          instructionsEnc.push(instruction);
        }
        
        let instructions = JSON.stringify(instructionsEnc);
        formData.append('instructions', instructions);
        formData.append('clasification', formValue.clasificationControl);

        let resourcesConf: any[] = [];
        for(const tool of formValue.toolsControl){
          if(tool == 'SH'){
            resourcesConf.push({
              ID: 'SH',
              REQ: '-',
              TYPE: 'T'
            });
          }else{
            let toolFilt = this.tools.filter(item => item.ID == tool);
            if(toolFilt.length > 0){
              let input = this._document.getElementById(`cant-req-${tool}`) as HTMLInputElement;
              if(input == null){
                this._resourcesService.openSnackBar(`No se pudo encontrar la configuración de la herramienta ${toolFilt[0].NOMB}.`);
                return;
              }

              let valStr = input.value;
              let valNum = parseInt(valStr);
              if(valNum <= 0){
                this._resourcesService.openSnackBar(`La cantidad configurada para la herramienta ${toolFilt[0].NOMB} no puede ser igual o menor a cero.`);
                return;
              }

              resourcesConf.push({
                ID: tool,
                REQ: valNum,
                TYPE: 'T'
              });
            }
          }
        }
  
        for(const sparePart of formValue.sparePartsControl){
          if(sparePart == 'SH'){
            resourcesConf.push({
              ID: 'SH',
              REQ: '-',
              TYPE: 'S'
            });
          }else{
            let partFilt = this.spareParts.filter(item => item.ID == sparePart);
            if(partFilt.length > 0){
              let input = this._document.getElementById(`cant-req-${sparePart}`) as HTMLInputElement;
              if(input == null){
                this._resourcesService.openSnackBar(`No se pudo encontrar la configuración de la refacción ${partFilt[0].NOMB}.`);
                return;
              }

              let valStr = input.value;
              let valNum = parseInt(valStr);
              if(valNum <= 0){
                this._resourcesService.openSnackBar(`La cantidad configurada para la refacción ${partFilt[0].NOMB} no puede ser igual o menor a cero.`);
                return;
              }

              resourcesConf.push({
                ID: sparePart,
                REQ: valNum,
                TYPE: 'S'
              });
            }
          }
        }

        formData.append('resources', JSON.stringify(resourcesConf));
        await lastValueFrom(this._prevMaintService.registerWorkOrder(formData));

        this._resourcesService.openSnackBar('La orden se guardó correctamente.');
        window.history.back();
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (23).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (24).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  goBack(steps: number){
    window.history.go(steps * -1);
  }
}
