import { Component, Inject, OnInit } from '@angular/core';
import { PreventiveMaintenanceService } from '../../../../services/preventive-maintenance.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { FunctionsService } from '../../../../services/functions.service';
import { ResourcesService } from '../../../../services/resources.service';
import { EncService } from '../../../../services/enc.service';
import { lastValueFrom } from 'rxjs';
import { PreventiveWorkOrderResponse } from '../../../../interfaces/preventive-work-order.interface';
import { EmployeeService } from '../../../../services/personal-management/employee.service';
import { EmployeesListItem, EmployeesListResponse } from '../../../../interfaces/personal-managment/employee.interface';

@Component({
    selector: 'app-order-execution-config',
    templateUrl: './order-execution-config.component.html',
    styleUrl: './order-execution-config.component.css',
    standalone: false
})
export class OrderExecutionConfigComponent implements OnInit {
  isLoading: boolean;
  hasError: boolean;
  errorStr: string;
  execDate: string;
  idOrder: number;
  staffArr: any[];
  employees: EmployeesListItem[];
  subcontratists: EmployeesListItem[];
  selectedStaff: Map<string, string[]>;
  excludedStaff: string[];
  enableStart: boolean;

  constructor(
    @Inject(MAT_DIALOG_DATA) private _data: any,
    private _preventiveMaintenanceService: PreventiveMaintenanceService,
    private _functionsService: FunctionsService,
    private _resourcesService: ResourcesService,
    private _encService: EncService,
    private _employeeService: EmployeeService,
    private _dialogRef: MatDialogRef<OrderExecutionConfigComponent>,
  ) {
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = '';
    this.execDate = '';
    this.idOrder = 0;
    this.staffArr = [];
    this.employees = [];
    this.subcontratists = [];
    this.selectedStaff = new Map();
    this.excludedStaff = [];
    this.enableStart = false;
  }

  ngOnInit(): void {
    this.execDate = this._functionsService.orderDate(this._data.date);
    this.idOrder = this._data.idOrder;

    this.getPreventiveOrder();
  }

  private async getPreventiveOrder(){
    try{
      let idOrderEnc = await this._encService.encrypt(`${this.idOrder}`);
      let idUser = localStorage.getItem('idusuario')!;
      let preventiveOrder: PreventiveWorkOrderResponse = await lastValueFrom(this._preventiveMaintenanceService.getWorkOrder(
        idOrderEnc,
        idUser,
        1
      ));
      
      this.hasError = preventiveOrder.error;
      this.errorStr = preventiveOrder.msg;

      if(this.hasError){
        this.isLoading = false;
      }else{
        let staffArr = JSON.parse(preventiveOrder.response.OPERARIOS);
        let staffArrFn: any[] = [];

        for(const item of staffArr){
          item.ID = await this._encService.decrypt(item.ID);
          staffArrFn.push(item);

          this.selectedStaff.set(item.ID, []);
        }

        this.staffArr = staffArrFn;
        this.getEmployees();
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

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

  private async getEmployees(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let employees: EmployeesListResponse = await lastValueFrom(this._employeeService.getConsultOfEmployees(idUser, 1));

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

      if(!this.hasError){
        let employeesArr: EmployeesListItem[] = [];
        let subcontratistsArr: EmployeesListItem[] = [];

        for(const employee of employees.response){
          if(employee.STATUS == 'Activo'){
            let idEmployeeDec = await this._encService.decrypt(employee.ID_EMPLOYEE);
            employee.NAME = `${employee.NAME} (${idEmployeeDec})`;

            let specialtiesArr: string[] = JSON.parse(employee.SPECIALITY);
            let specialties: string[] = [];

            for(const specialty of specialtiesArr){
              let specialtyDec = await this._encService.decrypt(specialty);
              specialties.push(specialtyDec);
            }

            employee.SPECIALITY_ARR = specialties;
            if(employee.CONTRACT_TYPE == 'Interno'){
              employeesArr.push(employee);
            }else{
              subcontratistsArr.push(employee);
            }
          }
        }

        this.employees = employeesArr;
        this.subcontratists = subcontratistsArr;
      }

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

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

  staffChange(specialty: string, value: string[]){
    if(this.selectedStaff.has(specialty)){
      this.selectedStaff.set(specialty, value);
    }

    let excludedStaff: string[] = [];
    for(const key of this.selectedStaff.keys()){
      let specialtyStaff = this.selectedStaff.get(key)!;
      for(const item of specialtyStaff){
        excludedStaff.push(item);
      }
    }

    this.excludedStaff = excludedStaff;
    let allEnded = true;

    for(const item of this.staffArr){
      let specialtyStaffSelected = this.selectedStaff.get(item.ID)!;
      if(specialtyStaffSelected.length != item.CANT){
        allEnded = false;
      }
    }

    this.enableStart = allEnded;
  }

  async startExec(){
    let dataObj: any = {};

    for(const key of this.selectedStaff.keys()){
      let specialtyStaff = this.selectedStaff.get(key);
      dataObj[key] = specialtyStaff;
    }

    let dataStr = JSON.stringify(dataObj);
    let dataEnc = await this._encService.encrypt(dataStr);

    this._dialogRef.close(dataEnc);
  }
}
