import { Component, Inject, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { EquipmentsListItem, EquipmentsListResponse } from '../../../../interfaces/equipment-management.interface';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { EquipmentManagementService } from '../../../../services/equipment-management.service';
import { EncService } from '../../../../services/enc.service';
import { lastValueFrom } from 'rxjs';
import { EquipmentDetailsDialogComponent } from '../equipment-details-dialog/equipment-details-dialog.component';

@Component({
    selector: 'app-search-equipment',
    templateUrl: './search-equipment.component.html',
    styleUrl: './search-equipment.component.css',
    standalone: false
})
export class SearchEquipmentComponent implements OnInit {
  isLoading: boolean;
  hasError: boolean;
  errorStr: string;

  dataSource: MatTableDataSource<EquipmentsListItem>;
  public txtBuscador: string;

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

  displayedColumns = ['CODIGO', 'TIPO', 'MODELO', 'ID_EQUIPO', 'ELEMENTO_ORIGEN', 'ACCIONES'];
  originElement: string;
  destinyElement: string;

  constructor(
    @Inject(MAT_DIALOG_DATA) private _data: any,
    private _equipmentManagementService: EquipmentManagementService,
    private _encService: EncService,
    private _dialog: MatDialog,
    private _dialogRef: MatDialogRef<SearchEquipmentComponent>,
  ) {
    this.isLoading = true;
    this.hasError = false,
    this.errorStr = '';

    this.dataSource = new MatTableDataSource();
    this.txtBuscador = '';
    this.originElement = "";
    this.destinyElement = "";
  }

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

  async init(){
    if(this._data.originElement != null && this._data.originElement != undefined && this._data.originElement != ''){
      this.originElement = await this._encService.decrypt(this._data.originElement);
    }
    
    if(this._data.destinyElement != null && this._data.destinyElement != undefined && this._data.destinyElement != ''){
      this.destinyElement = await this._encService.decrypt(this._data.destinyElement);
    }
    
    if(this._data.originCodificationType != null && this._data.equipmentType == 'origin'){
      this.getEquipmentsByCodeType(this._data.originCodificationType);
    }else if(this._data.destinyCodificationType != null && this._data.equipmentType == 'destiny'){
      this.getEquipmentsByCodeType(this._data.destinyCodificationType);
    }else if(this._data.codeType == '4'){
      let codeTypesEnc = await this._encService.encrypt('1|2|5');
      this.getEquipmentsByCodeType(codeTypesEnc);
    }else{
      this.getEquipments(); 
    }
  }

  async getEquipmentsByCodeType(codeType: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let equipments: EquipmentsListResponse = await lastValueFrom(this._equipmentManagementService.equipmentConsultByCodeType(
        codeType,
        idUser, 
        1
      ));

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

      if(!this.hasError){
        let equipmentsArr: EquipmentsListItem[] = [];
        for(const equipment of equipments.response){
          equipment.CODIGO = await this._encService.decrypt(equipment.CODIGO);
          let idDec = await this._encService.decrypt(equipment.ID_EQUIPO);
          let idEquipment = this.processEquipmentID(idDec);

          equipment.ID_EQUIPO = idEquipment;
          if(this.originElement != equipment.CODIGO && this.destinyElement != equipment.CODIGO){
            equipmentsArr.push(equipment);
          }
        }

        this.dataSource = new MatTableDataSource(equipmentsArr);
        this.dataSource.paginator = this.paginator!;
        this.dataSource.sort = this.sort!;
      }

      this.isLoading = false;
    }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 getEquipments() {
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let equipments: EquipmentsListResponse = await lastValueFrom(this._equipmentManagementService.equipmentConsult(idUser, 1));

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

      if(!this.hasError){
        let equipmentsArr: EquipmentsListItem[] = [];
        for(const equipment of equipments.response){
          equipment.CODIGO = await this._encService.decrypt(equipment.CODIGO);
          let idDec = await this._encService.decrypt(equipment.ID_EQUIPO);
          let idEquipment = this.processEquipmentID(idDec);

          equipment.ID_EQUIPO = idEquipment;
          if(this.originElement != equipment.CODIGO && this.destinyElement != equipment.CODIGO){
            equipmentsArr.push(equipment);
          }
        }

        this.dataSource = new MatTableDataSource(equipmentsArr);
        this.dataSource.paginator = this.paginator!;
        this.dataSource.sort = this.sort!;
      }

      this.isLoading = false;
    }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;
    }
  }

  private processEquipmentID(id: string): string{
    for(let i = id.length; i < 6; i++){
      id = `0${id}`;
    }
    return id;
  }

  // Método de filtrado de datos
  public applyFilter(event: any, type: string): void {
    let filterValue: string;
    if (type == 'INP') {
      filterValue = (event.target as HTMLInputElement).value;
    } else {
      this.txtBuscador = event;
      filterValue = event;
    }
    this.dataSource.filter = filterValue.trim().toLowerCase();
    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }

  async getEquipmentDetails(code: string){
    let codeEnc = await this._encService.encrypt(code);
    this._dialog.open(EquipmentDetailsDialogComponent, {
      width: '480px',
      maxWidth: '480px',
      data: {
        code: codeEnc,
      }
    })
  }

  async assignEquipment(code: string){
    let codeEnc = await this._encService.encrypt(code);
    this._dialogRef.close(codeEnc);
  }
}
