import { ErrorStateMatcher } from '@angular/material/core';
import { FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms';
import { Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { MatTableDataSource } from '@angular/material/table';
import { DOCUMENT } from '@angular/common';
import { availableFiles } from 'src/environments/environment.prod';
import { MatSnackBar } from '@angular/material/snack-bar';
import { TempFileInfo } from 'src/app/components/system-admin/advices/new-advice/new-advice.component';
import { interval, lastValueFrom } from 'rxjs';
import { EncService } from 'src/app/services/enc/enc.service';
import { SystemAdminService } from 'src/app/services/system-admin.service';
import { MatDialog } from '@angular/material/dialog';
import { SearchFileDialogComponent } from 'src/app/components/gdel/search-file-dialog/search-file-dialog.component';
import { FindedFile } from 'src/app/interfaces/finded-files.interface';
import { NewActivatorComponent } from './new-activator/new-activator.component';
import { CountersActivatorsService } from 'src/app/services/counters-activators.service';
import { ActivatorByType, ActivatorsByTypeResponse } from 'src/app/interfaces/activators-by-type.interface';
import { PreventiveMaintenanceService } from 'src/app/services/preventive-maintenance.service';
import { PreventiveWorkOrderResponse } from 'src/app/interfaces/preventive-work-order.interface';
import { Permissions } from 'src/app/interfaces/permissions.interface';
import { SocketService } from 'src/app/services/socket.service';
import { UserConsultResponse } from 'src/app/interfaces/user.interface';
import { UsersProfilesService } from 'src/app/services/users-profiles.service';
import { ProfileInterface } from 'src/app/interfaces/profile.interface';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { NewInstructionComponent } from './new-instruction/new-instruction.component';

interface EquipmentInfo{
  CODIGO: string;
  DENOMI: string;
  FAMILI: string;
  SUBFAM: string;
  ESTADO: string;
}
const EQUIPMENT_TMP: EquipmentInfo[] = [
  {
    CODIGO: '01.110.P01-15001.CAM_TCG.CTV.I.HICDE-X3G21-000001',
    DENOMI: 'Hickvision Cámara IP DOMO IR para Exteriores',
    FAMILI: 'Sistema de Telecomunicaciones',
    SUBFAM: 'Videovigilante',
    ESTADO: 'Instalado'
  },
  {
    CODIGO: '01.502.P01-09001.DIS_TN.FRN.I.PAFRE-XXOEM-000001',
    DENOMI: 'Pastillas de Freno',
    FAMILI: 'Tren Nuevo',
    SUBFAM: 'Sistema de Frenos',
    ESTADO: 'Instalado'
  },
  {
    CODIGO: '01.PCC.P01-13001.R42.B4-01_TC.RMS.I.ENCIS-NCC500-000002',
    DENOMI: 'Enrutador CISCO',
    FAMILI: 'Telecomunicaciones',
    SUBFAM: 'Red Multiservicios',
    ESTADO: 'Instalado'
  },
  {
    CODIGO: '01.PCC.P01-13001.R42.H7-06_TC.RMS.I.PAPCI-XXX96F-000001',
    DENOMI: 'Patch Panel Cisco',
    FAMILI: 'Telecomunicaciones',
    SUBFAM: 'Red Multiservicios',
    ESTADO: 'Instalado'
  },
  {
    CODIGO: '01.302.P01-14002.DVR.10,02:315.P01.14002-DVR.16,02_TCG.CTV.T.HICTU-HIM1-000020',
    DENOMI: 'Hickivision DVR de 16 Canales Turbo HD',
    FAMILI: 'Sistema de Telecomunicaciones',
    SUBFAM: 'Videovigilancia',
    ESTADO: 'Traslado'
  },
  {
    CODIGO: '01.110.S01-14001.UDF.17,08:160.UDF.S01-14001.18,08_V1.014.I.CALIG-XGB6KG-000100',
    DENOMI: 'Carril Ligero',
    FAMILI: 'Sistema de Vías',
    SUBFAM: 'Distribución de Durmientes',
    ESTADO: 'Instalado'
  },
  {
    CODIGO: '01.160.S01-03010.VEN.00010:110.P02-03010.VEN.00020_MEP.ACC.I.DUVEN-XXTDC-000002',
    DENOMI: 'Cable de Red',
    FAMILI: 'Telecomunicaciones',
    SUBFAM: 'Red Multiservicios',
    ESTADO: 'Instalado'
  }
];
interface TeamInfo{
  ID: string;
  NOMB: string;
  ESP: string;
}
const TEAMS_TMP: TeamInfo[] = [
  {ID: 'T1', NOMB: 'EQUIPO 1', ESP: 'Mécánica'},
  {ID: 'T2', NOMB: 'EQUIPO 2', ESP: 'Electrónica'},
  {ID: 'T3', NOMB: 'EQUIPO 3', ESP: 'Electricidad'},
  {ID: 'T4', NOMB: 'EQUIPO 4', ESP: 'Neumática'},
  {ID: 'T5', NOMB: 'EQUIPO 5', ESP: 'Hidráulica'},
  {ID: 'T6', NOMB: 'EQUIPO 6', ESP: 'Control'},
  {ID: 'T7', NOMB: 'EQUIPO 7', ESP: 'Frenado'},
  {ID: 'T8', NOMB: 'EQUIPO 8', ESP: 'Sistemas'},
  {ID: 'T9', NOMB: 'EQUIPO 9', ESP: 'Industrial'},
  {ID: 'T10', NOMB: 'EQUIPO 10', ESP: 'Civil'},
  {ID: 'T11', NOMB: 'EQUIPO 11', ESP: 'Redes'},
];
interface ToolInfo{
  ID: string;
  NOMB: string;
  MODE: string;
  CANTDISP: number;
  TYPE: string;
  UNIT: string;
}
const TOOLS_TMP: ToolInfo[] = [
  {ID: 'H1', NOMB: 'Pinzas eléctricas', MODE: 'PE-862', CANTDISP: 35, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H2', NOMB: 'Pinzas mecánicas', MODE: 'M985', CANTDISP: 27, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H3', NOMB: 'Pinzas de presión', MODE: 'RG-12', CANTDISP: 30, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H4', NOMB: 'Juego de llaves Allen', MODE: 'ALL88', CANTDISP: 75, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H5', NOMB: 'Extractor de rodamientos', MODE: 'EX-ROD-1500', CANTDISP: 3, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H6', NOMB: 'Kit llaves inglesas', MODE: '5530S', CANTDISP: 7, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H7', NOMB: 'Kit llaves españolas', MODE: '964F', CANTDISP: 8, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H8', NOMB: 'Juego de llaves Torx', MODE: 'TORX3423W', CANTDISP: 42, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H9', NOMB: 'Cautín de lápiz 33W', MODE: '33WCL', CANTDISP: 15, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H10', NOMB: 'Juego de dados milimétricos', MODE: 'DMM450', CANTDISP: 6, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H11', NOMB: 'Juego de dados pulgadas', MODE: 'DIN865', CANTDISP: 9, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H12', NOMB: 'Probador de corriente', MODE: '569', CANTDISP: 33, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H13', NOMB: 'Multímetro', MODE: 'TGH885', CANTDISP: 17, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H14', NOMB: 'Planta generadora para soldadura', MODE: 'PLAGEN-589', CANTDISP: 1, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H15', NOMB: 'Amperímetro de gancho', MODE: 'A0032', CANTDISP: 4, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H16', NOMB: 'Rotomartillo', MODE: '551', CANTDISP: 2, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H17', NOMB: 'Kit taladro inalámbrico', MODE: 'FP581', CANTDISP: 12, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H18', NOMB: 'Kit taládro alámbrico', MODE: 'HG862', CANTDISP: 10, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H19', NOMB: 'Juego de desarmadores', MODE: '8913-KSOA', CANTDISP: 5, TYPE: 'Herramienta', UNIT: 'Pieza'},
  {ID: 'H20', NOMB: 'Martillo', MODE: 'TS438', CANTDISP: 23, TYPE: 'Herramienta', UNIT: 'Pieza'},
];
const SPARE_PARTS_TMP: ToolInfo[] = [
  {ID: 'S1', NOMB: 'Neumático para NM-16', MODE: 'NM16NEU235', CANTDISP: 45, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S2', NOMB: 'Neumático para NM-22', MODE: 'NM22NEU652', CANTDISP: 51, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S3', NOMB: 'Rodamiento cónico', MODE: 'RC-4265', CANTDISP: 84, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S4', NOMB: 'Rodamiento axial', MODE: 'RA-5130', CANTDISP: 96, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S5', NOMB: 'Rodamiento angular', MODE: 'RN-3541', CANTDISP: 79, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S6', NOMB: 'Grasa 1-310', MODE: 'G1.310', CANTDISP: 9, TYPE: 'Refaccción', UNIT: 'Kilogramo'},
  {ID: 'S7', NOMB: 'Aceite 10W-40', MODE: 'A10W40', CANTDISP: 16, TYPE: 'Refaccción', UNIT: 'Litro'},
  {ID: 'S8', NOMB: 'Soldadura de estaño', MODE: 'LDA-913', CANTDISP: 39, TYPE: 'Refaccción', UNIT: 'Metro'},
  {ID: 'S9', NOMB: 'Soldadura de plata', MODE: 'BDA-516', CANTDISP: 21, TYPE: 'Refaccción', UNIT: 'Metro'},
  {ID: 'S10', NOMB: 'Pastilla de frenado', MODE: '754SSV', CANTDISP: 25, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S11', NOMB: 'Cable de cobre calibre 0', MODE: 'CC0-884', CANTDISP: 120, TYPE: 'Refaccción', UNIT: 'Metro'},
  {ID: 'S12', NOMB: 'Rosetas de cable Ethernet', MODE: '165-BFS', CANTDISP: 12, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S13', NOMB: 'Pintura', MODE: '53469', CANTDISP: 250, TYPE: 'Refaccción', UNIT: 'Litro'},
  {ID: 'S14', NOMB: 'Solvente de pintura', MODE: '2516', CANTDISP: 310, TYPE: 'Refaccción', UNIT: 'Litro'},
  {ID: 'S15', NOMB: 'Lámina galvanizada', MODE: 'SFAS-320', CANTDISP: 38, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S16', NOMB: 'Botón de freno de emergencia', MODE: 'B-51321', CANTDISP: 14, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S17', NOMB: 'Disco duro de estado sólido 512GB', MODE: 'SSD-512', CANTDISP: 22, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S18', NOMB: 'Mouse óptico', MODE: 'MO1165', CANTDISP: 26, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S19', NOMB: 'Teclado para PC', MODE: '5413', CANTDISP: 24, TYPE: 'Refaccción', UNIT: 'Pieza'},
  {ID: 'S20', NOMB: 'Cable HDMI 2m', MODE: 'ASD-181', CANTDISP: 6, TYPE: 'Refaccción', UNIT: 'Pieza'},
];
interface Instruction{
  ID: string,
  INSTRUCCION: string,
  ESPECIALIDADES: string[],
}
interface Magnitudes{
  MAGNITUDE: string;
  LABEL: string;
  UNITS: Units[];
}
interface Units{
  UNIT: string,
  LABEL: string,
}
const MAGNITUDES: Magnitudes[] = [
  {MAGNITUDE: 'TEM', LABEL: 'Temperatura', UNITS: [
    {UNIT: 'K', LABEL: '°K - Kelvin'},
    {UNIT: 'C', LABEL: '°C - Celsius'},
    {UNIT: 'F', LABEL: '°F - Fahrenheit'},
  ]},
  {MAGNITUDE: 'TEN', LABEL: 'Tensión', UNITS: [
    {UNIT: 'V', LABEL: 'V - Volts'},
  ]},
  {MAGNITUDE: 'COR', LABEL: 'Corriente', UNITS: [
    {UNIT: 'A', LABEL: 'A - Amperios'},
  ]},
  {MAGNITUDE: 'POT', LABEL: 'Potencia', UNITS: [
    {UNIT: 'W', LABEL: 'W - Watts'},
    {UNIT: 'HP', LABEL: 'HP - Caballos de fuerza'}
  ]},
  {MAGNITUDE: 'FRE', LABEL: 'Frecuencia', UNITS: [
    {UNIT: 'Hz', LABEL: 'Hz - Hertz'},
    {UNIT: 'RPM', LABEL: 'RPM - Revoluciones por minuto'},
  ]},
  {MAGNITUDE: 'VEL', LABEL: 'Velocidad', UNITS: [
    {UNIT: 'm/s', LABEL: 'm/s - Metros por segundo'},
    {UNIT: 'm/h', LABEL: 'm/h - Metros por hora'},
    {UNIT: 'km/h', LABEL: 'km/h - Kilometros por hora'},
  ]},
  {MAGNITUDE: 'DIS', LABEL: 'Distancia', UNITS: [
    {UNIT: 'cm', LABEL: 'cm - Centímetros'},
    {UNIT: 'm', LABEL: 'm - Metros'},
    {UNIT: 'km', LABEL: 'km - Kilometros'},
    {UNIT: 'in', LABEL: 'in - Pulgada'},
    {UNIT: 'ft', LABEL: 'ft - Pies'},
    {UNIT: 'yd', LABEL: 'yd - Yarda'},
  ]}
];
@Component({
  selector: 'app-new-work-order',
  templateUrl: './new-work-order.component.html',
  styleUrls: ['./new-work-order.component.css']
})
export class NewWorkOrderComponent implements OnInit {
  isUploading: boolean;
  isLoading: boolean;
  hasError: boolean;
  isNew: boolean;
  loadingActivators: boolean;
  errorStr: string;
  action: string;
  idOrder: string | null;
  hoursArr: string[];
  equipments: EquipmentInfo[];
  teams: TeamInfo[];
  tools: ToolInfo[];
  spareParts: ToolInfo[];
  attached: TempFileInfo[];
  toolsParts: ToolInfo[];
  activators: ActivatorByType[];

  dataSource?: MatTableDataSource<EquipmentInfo>;
  displayedColumns = ['CODIGO', 'DENOMI', 'FAMILI', 'SUBFAM', 'ESTADO', 'ACCIONES'];

  teamsDataSource?: MatTableDataSource<TeamInfo>;
  teamsDisplayedColumns = ['EQUIPO', 'ESPECIALIDAD', 'OPERARIOS'];

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

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

  toolsDataSource?: MatTableDataSource<ToolInfo>;
  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[];
  magnitudes: Magnitudes[];

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

  constructor(
    private _activatedRoute: ActivatedRoute,
    @Inject(DOCUMENT) private _document: Document,
    private _snackBar: MatSnackBar,
    private _encService: EncService,
    private _systemAdminService: SystemAdminService,
    private _dialog: MatDialog,
    private _countersActivatorsService: CountersActivatorsService,
    private _prevMaintService: PreventiveMaintenanceService,
    private _socketService: SocketService,
    private _usersProfilesSevice: UsersProfilesService, 
    private _router: Router,
  ) { 
    this.isUploading = false;
    this.isLoading = true;
    this.hasError = false;
    this.isNew = false;
    this.loadingActivators = false;
    this.errorStr = "";
    this.action = "";
    this.idOrder = null;
    this.hoursArr = [];
    this.dataSource = new MatTableDataSource();
    this.equipments = EQUIPMENT_TMP;
    this.teams = TEAMS_TMP;
    this.teamsDataSource = new MatTableDataSource();
    this.tools = TOOLS_TMP;
    this.spareParts = SPARE_PARTS_TMP;
    this.attached = [];
    this.activators = [];

    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.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(35)]),
      inmTimeControl: new FormControl('', [Validators.required, Validators.pattern('[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')]),
      totalTimeControl: new FormControl('', [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)]),
    });

    this.instructions = [];
    this.magnitudes = MAGNITUDES;
  }

  ngOnInit(): void {
    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 shortID = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('idusuario')!));
      let usrInfo: UserConsultResponse = await lastValueFrom(this._usersProfilesSevice.getUser(shortID.response.encrypted, shortID.response.encrypted, 1));
      let currentProfile = await this._encService.desencriptar(localStorage.getItem('perfil')!);

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

      let profileUpdated = await this._encService.desencriptar(`${profUpdEnc}`);
      if(profileUpdated == currentProfile){
        try{
          let shortProf = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('perfil')!));
          let profInfo: ProfileInterface = await lastValueFrom(this._usersProfilesSevice.getProfile(
            shortProf.response.encrypted,
            shortID.response.encrypted,
            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.openSnackBar('Ocurrió un error al actualizar su perfil');
          }else if(error.error.msg == undefined){
            this.openSnackBar('Ocurrió un error al actualizar su perfil');
          }else{
            this.openSnackBar(error.error.msg);
          }
        }
      }
    })

    for(let i = 0; i < 24; i++){
      let period = i < 12 ? 'AM' : 'PM';
      let hour = i > 12 ? i - 12 : i;
      
      this.hoursArr.push(`${hour}:00 ${period}`);
      this.hoursArr.push(`${hour}:15 ${period}`);
      this.hoursArr.push(`${hour}:30 ${period}`);
      this.hoursArr.push(`${hour}:45 ${period}`);
    }
  }

  async getProfileAccess(idOrder: string){
    try{
      let permissionsEnc = localStorage.getItem('permisos');
      let permissionsDec = await this._encService.desencriptar(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.isLoading = false;
      }else{
        this.getWorkOrder(idOrder);
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado';
      }else{
        this.errorStr = error.error.msg;
      }

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

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

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

      if(!this.hasError){
        if(order.response.ACTIVADOR != null){
          this.orderFormGroup.controls['activatorTypeControl'].setValue(order.response.TIPOACTIVADOR);
          this.getActivatorsByType(order.response.TIPOACTIVADOR!, order.response.ACTIVADOR);
        }

        if(order.response.FECHAINICIO != ''){
          let startDateArr = order.response.FECHAINICIO.split('-');
          let startDate = new Date(parseInt(startDateArr[0]), parseInt(startDateArr[1]) - 1, parseInt(startDateArr[2]));
          this.orderFormGroup.controls['startDateControl'].setValue(startDate);
          this.orderFormGroup.controls['startHourControl'].setValue(order.response.HORAINICIO);
        }
        
        if(order.response.FECHAFINAL != ''){
          let endDateArr = order.response.FECHAFINAL.split('-');
          let endDate = new Date(parseInt(endDateArr[0]), parseInt(endDateArr[1]) - 1, parseInt(endDateArr[2]));
          this.orderFormGroup.controls['endDateControl'].setValue(endDate);
          this.orderFormGroup.controls['endHourControl'].setValue(order.response.HORAFINAL);
        }
        
        this.orderFormGroup.controls['equipmentControl'].setValue(order.response.EQUIPAMIENTO);
        this.changeEquipmentTable(order.response.EQUIPAMIENTO);

        this.orderFormGroup.controls['descriptionControl'].setValue(order.response.DESCRIPCION);
        if(order.response.INSTRUCCIONES != '{}'){
          this.instructions = JSON.parse(order.response.INSTRUCCIONES);
          this.updateTeamsTable();
          this.teamsConf = JSON.parse(order.response.OPERARIOS);
        }
        
        this.orderFormGroup.controls['totalTimeControl'].setValue(`${order.response.DURACIONTOTAL}`);
        this.orderFormGroup.controls['inmTimeControl'].setValue(`${order.response.TIEMPOINMOESTI}`);
        this.orderFormGroup.controls['clasificationControl'].setValue(`${order.response.CLASIFICACION}`);

        let resources = JSON.parse(order.response.RECURSOS);
        let resCont = 0;
        resources.forEach((item: any) => {
          let idDec = item.ID;
          if(item.TYPE == 'T'){
            this.toolsConf[idDec] = item.REQ == '-' ? 0 : parseInt(item.REQ);
          }else{
            this.partsConf[idDec] = item.REQ == '-' ? 0 : parseInt(item.REQ);
          }

          resCont++;
          if(resCont >= resources.length){
            let tools = Object.keys(this.toolsConf) as never[];
            this.orderFormGroup.controls['toolsControl'].setValue(tools);

            let parts = Object.keys(this.partsConf) as never[];
            this.orderFormGroup.controls['sparePartsControl'].setValue(parts);
            
            this.toolsChange(tools, parts);
          }
        });

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

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

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

  initTables(){
    setTimeout(() => {
      let teamsKeys = Object.keys(this.teamsConf);
      teamsKeys.forEach(key => {
        let input = this._document.getElementById(`OP-${key}`) as HTMLInputElement;
        input.value = this.teamsConf[key];
      });

      let toolsKeys = Object.keys(this.toolsConf);
      toolsKeys.forEach(key => {
        if(key != 'SH'){
          let input = this._document.getElementById(`cant-req-${key}`) as HTMLInputElement;
          input.value = this.toolsConf[key];
        }
      });

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

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

  changeEquipmentTable(equimpentCode: string){
    let equipment = this.equipments.filter(item => item.CODIGO == equimpentCode);
    this.dataSource = new MatTableDataSource(equipment);
  }

  changeTeamsTable(teams: string[]){
    let teamsArr: TeamInfo[] = [];
    teams.forEach(item => {
      let team = this.teams.filter(item2 => item2.ID == item)[0];
      teamsArr.push(team);
    });

    this.teamsDataSource = new MatTableDataSource(teamsArr);
  }

  validateInput(value: string, id: string){
    let numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    let input = this._document.getElementById(`OP-${id}`) as HTMLInputElement;
    let valArr = value.split('');
    let valStr = "";

    for(let i = 0; i < valArr.length; i++){
      let char = valArr[i];
      if(numbers.includes(char)){
        valStr += char;
      }
    }

    input.value = valStr;
  }

  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.openSnackBar(`Los archivos ${extStr} no están soportados`);
    }else{
      let maxFileSize = 1048576 * maxSizeMB;
      let fileSize = event.target.files[0].size;

      if(fileSize > maxFileSize){
        this.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.openSnackBar("El archivo seleccionado ya fue adjuntado.");
        }else{
          this.isUploading = true;
          this.uploadTmp(event.target.files[0]);
        }
      }
    }
  }

  async uploadTmp(fileData: any){
    try{
      let idUser = localStorage.getItem('idusuario');
      let idUserShort = await lastValueFrom(this._encService.shortEncrypt(idUser!));

      var myFormData = new FormData();
      myFormData.append('file', fileData);
      myFormData.append('id_user', idUserShort.response.encrypted);
      myFormData.append('linea', "1");

      let response = await lastValueFrom(this._systemAdminService.uploadTempFile(myFormData));

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

        this.attached.push(uploadedFile);
      }

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

  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];
  }

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

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

  searchExistingFile(){
    let dialogRef = this._dialog.open(SearchFileDialogComponent, {
      width: '1024px'
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ""){
        let files: FindedFile[] = JSON.parse(res);
        files.forEach(async (item) => {
          let idFile = `${item.CODIGO}=${item.VERSION}=${item.NOMBRE}`;
          let fileEnc = await this._encService.encriptar(idFile);
          let file: TempFileInfo = {
            id: fileEnc,
            name: item.NOMBRE,
            size: this.formatBytes(item.TAMANIO),
            type: 'Existente'
          };

          this.attached.push(file);
        });
      }
    });
  }

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

  async deleteFile(id: string, type: string){
    try{
      if(type == 'Nuevo'){
        let idUser = localStorage.getItem('idusuario');
        let idUserShort = await lastValueFrom(this._encService.shortEncrypt(idUser!));

        await lastValueFrom(this._systemAdminService.deleteTempFile({
          'id_user': idUserShort.response.encrypted,
          'id_file': id,
          'linea': 1,
        }));
      }

      let attachedAux: TempFileInfo[] = [];
      this.attached.forEach(item => {
        if(item.id != id){
          attachedAux.push(item);
        }
      });

      this.attached = attachedAux;
    }catch(error: any){
      if(error.error == undefined){
        this.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this.openSnackBar(error.error.msg);
      }
    }
  }

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

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

    let partsAux: ToolInfo[] = [];
    if(partsValue != undefined && !partsValue.includes('SH')){
      partsValue.forEach(item => {
        let part = this.spareParts.filter(item2 => item == item2.ID)[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);
  }

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

  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}`;
  }

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

  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';
    }
  }

  async getActivatorsByType(type: string, selectedActivator: number | null){
    try{
      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 shortEnc = await lastValueFrom(this._encService.shortEncrypt(idUser!));
      let activators: ActivatorsByTypeResponse = await lastValueFrom(this._countersActivatorsService.getActivatorsByType(
        typeStr, 
        shortEnc.response.encrypted, 
        1
      ));

      if(activators.error){
        this.orderFormGroup.controls['activatorTypeControl'].setValue('');
        this.orderFormGroup.controls['activatorControl'].setValue(0);
        this.openSnackBar(activators.msg);
      }else{
        this.orderFormGroup.controls['activatorControl'].enable();
        this.activators = activators.response;
        if(selectedActivator != null){
          this.orderFormGroup.controls['activatorControl'].setValue(selectedActivator!);
        }
      }

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

  getPriorityStr(priority: string): string{
    if(priority == '1'){
      return 'Muy alta';
    }else if(priority == '2'){
      return 'Alta';
    }else if(priority == '3'){
      return 'Media';
    }else if(priority == '4'){
      return 'Baja';
    }

    return '';
  }

  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.orderFormGroup.controls['startHourControl'].disable();

    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.orderFormGroup.controls['endHourControl'].disable();

    if(value == 'CAN'){
      let dialogRef = this._dialog.open(NewActivatorComponent, {
        width: '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{
      let activator = this.activators.filter(item => item.IDCONTADOR == value)[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['startHourControl'].enable();
        this.orderFormGroup.controls['endDateControl'].enable();
        this.orderFormGroup.controls['endHourControl'].enable();
      }
    }
  }

  getActivatorConfigStr(type: string): string{
    if(this.orderFormGroup.controls['activatorControl'].value == 'CAN'){
      return "";
    }
    
    let activator = this.activators.filter(item => item.IDCONTADOR == this.orderFormGroup.controls['activatorControl'].value)[0];
    let conditionsObj = JSON.parse(activator.CONDICIONES);
    let configStr = "";
    
    if(type == 'CA' || type == 'SI'){
      switch(conditionsObj.repeat){
        case "NR": 
          let repeatDateNr = new Date(conditionsObj.startDate);
          this.orderFormGroup.controls['startDateControl'].setValue(repeatDateNr);
          this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
          
          configStr += "La orden no se repite"; 
        break;
        case "AN":
          let repeatDateAn= new Date(conditionsObj.startDate);
          configStr += `La orden se repite anualmente el día ${repeatDateAn.getDate()} de ${this.MONTHS[repeatDateAn.getMonth()]}`;

          this.orderFormGroup.controls['startDateControl'].setValue(repeatDateAn);
          this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
        break;
        case "ME":
          let repeatDateMe = new Date(conditionsObj.startDate);
          configStr += `La orden se repite mensualmente los días ${repeatDateMe.getDate()}`;

          this.orderFormGroup.controls['startDateControl'].setValue(repeatDateMe);
          this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
        break;
        case "SE":
          let repeatDateSe = new Date(conditionsObj.startDate);
          configStr += `La orden se repite semanalmente los días ${this.dayNames[repeatDateSe.getDay()]}`;

          this.orderFormGroup.controls['startDateControl'].setValue(repeatDateSe);
          this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
        break;
        case "TD":
          let repeatDateTd = new Date(conditionsObj.startDate);
          configStr += `La orden se repite todos los días desde el ${repeatDateTd.getDate()} de ${this.MONTHS[repeatDateTd.getMonth()]} del ${repeatDateTd.getFullYear()}`;

          this.orderFormGroup.controls['startDateControl'].setValue(repeatDateTd);
          this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
        break;
        case "PE":
          let repeatDatePe = new Date(conditionsObj.startDate);
          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 += `La orden se repite cada ${intervalA} días `;
              }else{
                configStr += `La orden se repite cada día `;
              }
            break;
            case "1":
              let intervalB = parseInt(repeatEvery[0]);
              if(intervalB > 1){
                configStr += `La orden se repite cada ${intervalB} semanas `;
              }else{
                configStr += `La 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 += `La orden se repite cada ${intervalC} meses `;
              }else{
                configStr += `La orden se repite cada mes `;
              }
            break;
            case "3":
              let intervalD = parseInt(repeatEvery[0]);
              if(intervalD > 1){
                configStr += `La orden se repite cada ${intervalD} años `;
              }else{
                configStr += `La orden se repite cada año `;
              }
            break;
          }

          configStr += `a partir del ${repeatDatePe.getDate()} de ${this.MONTHS[repeatDatePe.getMonth()]} del ${repeatDatePe.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.orderFormGroup.controls['endHourControl'].enable();
          }else if(endsAt[0] == 'A'){
            configStr += `finaliza después de ${endsAt[2]} repetici${parseInt(endsAt[2]) > 1 ? 'ones' : 'ón'}.`;
          }
          
          this.orderFormGroup.controls['startDateControl'].setValue(repeatDatePe);
          this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
        break;
      }
    }else{
      if(conditionsObj.customUnit != null){
        configStr += `Magnitud medida: ${conditionsObj.customMagnitude}. `;
        configStr += `Unidad configurada: ${conditionsObj.customUnit}. `;
      }else{
        let magnitude = this.magnitudes.filter(item => item.MAGNITUDE == conditionsObj.magnitude)[0];
        let unit = magnitude.UNITS.filter(item => item.UNIT == conditionsObj.unit)[0];

        configStr += `Magnitud medida: ${magnitude.LABEL}. `;
        configStr += `Unidad configurada: ${unit.LABEL}. `;
      }

      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.";
        }
      }
    }
    
    return configStr;
  }

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

      if(formValue.descriptionControl == ''){
        formData.append('description', '-');
      }else{
        formData.append('description', formValue.descriptionControl);
      }

      if(formValue.startDateControl == null){
        formData.append('startDate', '-');
      }else{
        formData.append('startDate', `${formValue.startDateControl.getFullYear()}-${formValue.startDateControl.getMonth() + 1}-${formValue.startDateControl.getDate()}`);
      }

      if(formValue.startHourControl == ''){
        formData.append('startHour', '-');
      }else{
        formData.append('startHour', formValue.startHourControl);
      }

      if(formValue.endDateControl == null){
        formData.append('endDate', '-');
      }else{
        formData.append('endDate', `${formValue.endDateControl.getFullYear()}-${formValue.endDateControl.getMonth() + 1}-${formValue.endDateControl.getDate()}`);
      }

      if(formValue.endHourControl == ''){
        formData.append('endHour', '-');
      }else{
        formData.append('endHour', formValue.endHourControl);
      }

      if(formValue.equipmentControl == ''){
        formData.append('equipment', '-');
      }else{
        formData.append('equipment', formValue.equipmentControl);
      }

      if(formValue.inmTimeControl == ''){
        formData.append('inmTime', '-');
      }else{
        formData.append('inmTime', formValue.inmTimeControl);
      }

      if(formValue.totalTimeControl == ''){
        formData.append('totalTime', '-');
      }else{
        formData.append('totalTime', formValue.totalTimeControl);
      }

      if(formValue.toolsControl.length == 0){
        formData.append('tools', '-');
        formData.append('toolsConf', '{}');
      }else{
        formData.append('tools', JSON.stringify(formValue.toolsControl));
        let toolsObj = {};
        formValue.toolsControl.forEach((tool: never) => {
          if(tool == 'SH'){
            toolsObj[tool] = '-' as never;
          }else{
            let input = this._document.getElementById(`cant-req-${tool}`) as HTMLInputElement;
            toolsObj[tool] = input.value as never;
          }
        });
        formData.append('toolsConf', JSON.stringify(toolsObj));
      }

      if(formValue.sparePartsControl.length == 0){
        formData.append('spareParts', '-');
        formData.append('sparePartsConf', '{}');
      }else{
        formData.append('spareParts', JSON.stringify(formValue.sparePartsControl));
        let partsObj = {};
        formValue.sparePartsControl.forEach((part: never) => {
          if(part == 'SH'){
            partsObj[part] = '-' as never;
          }else{
            let input = this._document.getElementById(`cant-req-${part}`) as HTMLInputElement;
            partsObj[part] = input.value as never;
          }
        });
        formData.append('sparePartsConf', JSON.stringify(partsObj));
      }

      formData.append('attached', JSON.stringify(this.attached));

      if(formValue.activatorTypeControl == ''){
        formData.append('activatorType', '-');
      }else{
        formData.append('activatorType', formValue.activatorTypeControl);
      }

      if(formValue.activatorControl == 0){
        formData.append('activator', '-');
      }else{
        formData.append('activator', `${formValue.activatorControl}`);
      }
      
      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.teamsDataSource?.data.length == 0){
        formData.append('teams', '-');
        formData.append('teamsConf', '{}');
      }else{
        formData.append('teams', JSON.stringify(this.teamsDataSource?.data));
        let teamsObj = {};
        this.teamsDataSource?.data.forEach(team => {
          let input = this._document.getElementById(`OP-${team.ID}`) as HTMLInputElement;
          let objKey = team.ID as never;
          teamsObj[objKey] = input.value as never;
        });
        formData.append('teamsConf', JSON.stringify(teamsObj));
      }

      if(this.instructions.length == 0){
        formData.append('instructions', '{}');
      }else{
        formData.append('instructions', JSON.stringify(this.instructions));
      }
      
      if(formValue.clasificationControl == ''){
        formData.append('clasification', '-');
      }else{
        formData.append('clasification', formValue.clasificationControl);
      }
      
      await lastValueFrom(this._prevMaintService.savePresetWorkOrder(formData));

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

  async registerWorkOrder(){
    try{
      if(this.orderFormGroup.invalid){
        this.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 startDate = `${formValue.startDateControl.getFullYear()}-${formValue.startDateControl.getMonth() + 1}-${formValue.startDateControl.getDate()}`;
        let endDate = formValue.endDateControl == null ? null : `${formValue.endDateControl.getFullYear()}-${formValue.endDateControl.getMonth() + 1}-${formValue.endDateControl.getDate()}`;

        formData.append('id_user', idUser!);
        formData.append('linea', '1');
        formData.append('description', formValue.descriptionControl!);
        formData.append('start_date', startDate);
        formData.append('start_hour', formValue.startHourControl!);
        
        if(endDate != null){
          formData.append('end_date', endDate!);
          formData.append('end_hour', formValue.endHourControl!);
        }
        
        formData.append('equipment', formValue.equipmentControl!);
        formData.append('inm_time', formValue.inmTimeControl!);
        formData.append('total_time', formValue.totalTimeControl!);
        formData.append('teams', JSON.stringify(this.teamsDataSource?.data));

        let teamsConf = {};
        let validConf = true;
        this.teamsDataSource?.data.forEach(item => {
          let input = this._document.getElementById(`OP-${item.ID}`) as HTMLInputElement;
          if(input.value == ''){
            let team = this.teams.filter(item2 => item2.ID == item.ID)[0];
            this.openSnackBar(`El número de operadores para el equipo '${team.NOMB} - ${team.ESP}' no se ha configurado`);
            
            validConf = false;
          }else{
            let key = item.ID as never;
            teamsConf[key] = input.value as never;
          }
        });

        if(validConf){
          formData.append('teams_conf', JSON.stringify(teamsConf));

          let toolsConf: any[] = [];
          let validTools = true;
          formValue.toolsControl.forEach((item: string) => {
            if(item == 'SH'){
              toolsConf.push({
                ID: 'SH',
                REQ: '-',
                TYPE: 'T'
              });
            }else{
              let input = this._document.getElementById(`cant-req-${item}`) as HTMLInputElement;
              let tool = this.tools.filter(item2 => item2.ID == item)[0];
              if(input.value == ''){
                this.openSnackBar(`La cantidad requerida no se ha configurado para la herramienta ${tool.NOMB}`);
  
                validTools = false;
              }else{
                toolsConf.push({
                  ID: tool.ID,
                  REQ: input.value,
                  TYPE: 'T'
                });
              }
            }
          });

          formValue.sparePartsControl.forEach((item: string) => {
            if(item == 'SH'){
              toolsConf.push({
                ID: 'SH',
                REQ: '-',
                TYPE: 'S'
              });
            }else{
              let input = this._document.getElementById(`cant-req-${item}`) as HTMLInputElement;
              let part = this.spareParts.filter(item2 => item2.ID == item)[0];
              if(input.value == ''){
                this.openSnackBar(`La cantidad requerida no se ha configurado para la herramienta ${part.NOMB}`);
  
                validTools = false;
              }else{
                toolsConf.push({
                  ID: part.ID,
                  REQ: input.value,
                  TYPE: 'S'
                });
              }
            }
          });

          if(validTools){
            formData.append('resources', JSON.stringify(toolsConf));
            formData.append('activator', `${formValue.activatorControl!}`);
            formData.append('attached', JSON.stringify(this.attached));
            formData.append('clasification', formValue.clasificationControl);
            formData.append('exists', this.isNew ? 'N' : 'S');

            if(!this.isNew){
              formData.append('id_order', this.idOrder!);
            }
            
            if(this.instructions.length == 0){
              this.openSnackBar('La orden de be contener al menos una instrucción.');
            }else{
              formData.append('instructions', JSON.stringify(this.instructions));
              await lastValueFrom(this._prevMaintService.registerWorkOrder(formData));

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

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

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

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

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        let resArr = res.split('|');
        let spe = JSON.parse(resArr[1]);
        let now = (new Date()).getTime();

        if(type == 'new'){
          let instruction: Instruction = {
            ID: `${now}`,
            INSTRUCCION: resArr[0],
            ESPECIALIDADES: spe
          };

          this.instructions.push(instruction);
        }else{
          ins[0].INSTRUCCION = resArr[0];
          ins[0].ESPECIALIDADES = spe;
        }

        this.updateTeamsTable();
      }
    });
  }

  updateTeamsTable(){
    let selectedTeams: TeamInfo[] = [];
    this.instructions.forEach(item => {
      item.ESPECIALIDADES.forEach(item2 => {
        let exists = selectedTeams.filter(team => team.ID == item2);
        if(exists.length == 0){
          let team = this.teams.filter(team2 => team2.ID == item2)[0];
          selectedTeams.push(team);
        }
      });
    });

    this.teamsDataSource = new MatTableDataSource(selectedTeams);
  }

  getSpecialtiesStr(specialties: string[]): string{
    let specialtiesStr = "";
    specialties.forEach(item => {
      let speObj = this.teams.filter(item2 => item2.ID == item)[0];
      specialtiesStr += `${speObj.NOMB} - ${speObj.ESP}, `;
    });

    specialtiesStr = specialtiesStr.substring(0, specialtiesStr.length - 2);
    return specialtiesStr;
  }

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

export class WorkOrderStateMatcher implements ErrorStateMatcher{
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    const isSubmitted = form && form.submitted;
    return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
  }
}