import { Component, Inject, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { DataFamilies, DataSubfamilies, ResponseDataFamilies } from '../../../../interfaces/acquisition-management/artitle.interface';
import { GetAreaWarehouse, GetLevelAreaWarehouse, GetWarehouse, GetZoneLevelAreaWarehouse, ResponseDataGetAreaWarehouse, ResponseDataGetLevelAreaWarehouse, ResponseDataGetWarehouse, ResponseDataGetZoneLevelAreaWarehouse } from '../../../../interfaces/inventory-management/warehouse-management.interface';
import { GetProvidersActives, ResponseDataGetProvidersActives } from '../../../../interfaces/acquisition-management/provider.interface';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { DetailsMultiCriteria, RequestFormSearch, ResponseDataGetInfoByStock } from '../../../../interfaces/inventory-management/multi-criteria-search.interface';
import { ResourcesService } from '../../../../services/resources.service';
import { InventoryManagementService } from '../../../../services/inventory-management/inventory-management.service';
import { AcquisitionService } from '../../../../services/acquisition-management/acquisition.service';
import { ProviderService } from '../../../../services/acquisition-management/provider.service';
import { EncService } from '../../../../services/enc.service';
import { lastValueFrom } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';

@Component({
    selector: 'app-form-search',
    templateUrl: './form-search.component.html',
    styleUrl: './form-search.component.css',
    standalone: false
})
export class FormSearchComponent implements OnInit {
  public isLoading: boolean;
  public isLoadingForm: boolean;
  public formGroup: FormGroup;

  public arrFamilies: Array<DataFamilies>;
  public arrSubfamilies: Array<DataSubfamilies>;
  
  public arrWarehouse: Array<GetWarehouse>;
  public arrAreas: Array<GetAreaWarehouse>;
  public arrLevel: Array<GetLevelAreaWarehouse>;
  public arrZone: Array<GetZoneLevelAreaWarehouse>;
  public arrProviders: Array<GetProvidersActives>;

  public searchingArea: boolean;
  public searchingLevel: boolean;
  public searchingZone: boolean;
  public enableSearch: boolean;

  constructor(
    @Inject(MAT_DIALOG_DATA) public detailsMultiCriteria: DetailsMultiCriteria,
    public resourcesService: ResourcesService,
    private _inventoryManagementService: InventoryManagementService,
    private _acquisitionServices: AcquisitionService,
    private _providerService: ProviderService,
    private _encService: EncService,
    private _dialogReg: MatDialogRef<boolean | RequestFormSearch>,
  ) {
    this.isLoading = false;
    this.isLoadingForm = false;
    this.formGroup = this._createFormGroup();
    this.arrFamilies = [];
    this.arrSubfamilies = [];

    this.arrWarehouse = [];
    this.arrAreas = [];
    this.arrLevel = [];
    this.arrZone = [];
    this.arrProviders = [];

    this.searchingArea = false;
    this.searchingLevel = false;
    this.searchingZone = false;
    this.enableSearch = false;
  }

  private _createFormGroup() {
    return new FormGroup({
      'ID_STOCK': new FormControl(null),
      'CODIGO_EQUIPAMIENTO': new FormControl(null),
      'ID_UBICACION': new FormControl(null),
      'FAMILIA': new FormControl(null),
      'SUBFAMILIA': new FormControl({ value: null, disabled: this.detailsMultiCriteria.typeForm === 'search' }),
      'MODELO': new FormControl(null),
      'CODIGO_MODELO': new FormControl(null),
      'ALMACEN': new FormControl(null),
      'AREA': new FormControl({ value: null, disabled: this.detailsMultiCriteria.typeForm === 'search' }),
      'NIVEL': new FormControl({ value: null, disabled: this.detailsMultiCriteria.typeForm === 'search' }),
      'ZONA': new FormControl({ value: null, disabled: this.detailsMultiCriteria.typeForm === 'search' }),
      'TIPO_ADQUISICION': new FormControl(null),
      'NUMERO_PROVEEDOR': new FormControl(null),
      'CODIGO_BARRAS': new FormControl(null),
      'FECHA_VENCIMIENTO': new FormControl(null),
      'STOCK_MINIMO': new FormControl(null),
      'STOCK_MAXIMO': new FormControl(null),
      'ESTADO': new FormControl(null),
      'CONSUMIBLE': new FormControl(null),
      'REPARABLE': new FormControl(null),
    });
  }
  
  async ngOnInit() {
    this.initFormControlsListeners();

    this.isLoading = true;
    await this._getFamiliesAndSubfamilies();
    await this._getWarehouseActives();
    await this._getProvidersActive();
    await this.getDetailsMultiCriteria();
    this.isLoading = false;

    this.formGroup.controls['FAMILIA'].valueChanges.subscribe((family) => {
      if (family !== null && family !== '') {        
        this.arrSubfamilies = family.SUBFAMILIAS;
        this.formGroup.controls['SUBFAMILIA'].enable();
      } else {
        this.formGroup.controls['SUBFAMILIA'].disable();
      }
    });

    this.formGroup.controls['ALMACEN'].valueChanges.subscribe(async (almacen) => {
      if (almacen === null || almacen === '') {
        return;
      }
      await this.searchArea();
    });
    this.formGroup.controls['AREA'].valueChanges.subscribe(async (area) => {
      if (area === '' || area === null) {
        return;
      }
      await this.searchLevel();
    });
    this.formGroup.controls['NIVEL'].valueChanges.subscribe(async (nivel) => {
      if (nivel === '' || nivel === null) {
        return;
      }
      await this.searchZone();
    });
  }

  private initFormControlsListeners(){
    let controls = Object.keys(this.formGroup.getRawValue());
    for(const control of controls){
      if(this.formGroup.contains(control)){
        this.formGroup.controls[control].valueChanges.subscribe((_) => this.validateFormValue());
      }
    }
  }

  private validateFormValue(){
    let controls = Object.keys(this.formGroup.getRawValue());
    let filledValues = 0;

    for(const control of controls){
      if(this.formGroup.contains(control)){
        let value = this.formGroup.controls[control].value;
        if(value != null && value != undefined && value != ''){
          filledValues++;
        }
      }
    }
    
    this.enableSearch = filledValues > 0;
  }

  private async _getFamiliesAndSubfamilies() {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._acquisitionServices.getFamiliesAndSubfamilies(user, line)).then(
      (responseData:ResponseDataFamilies) => {
        if ( !responseData.error ) {
          this.arrFamilies = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this._getFamiliesAndSubfamilies();
        }
      }
    );
  }

  private async _getWarehouseActives() {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._inventoryManagementService.getWarehouseActives(user, line)).then(
      async (responseData: ResponseDataGetWarehouse) => {
        if (!responseData.error) {
          this.arrWarehouse = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this._getWarehouseActives();
        }
      }
    );
  }

  private async _getProvidersActive() {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._providerService.getProviderActives(user, line)).then(
      (responseData: ResponseDataGetProvidersActives) => {
        if (!responseData.error) {
          this.arrProviders = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this._getProvidersActive();
        }
      }
    );
  }
  
  private async getDetailsMultiCriteria() {
    if (this.detailsMultiCriteria.typeForm === 'readonly' && this.detailsMultiCriteria.idStock !== null) {
      const encStock = await this._encService.encrypt(this.detailsMultiCriteria.idStock);
      const user: string = this.resourcesService.getUser();
      const line: number = this.resourcesService.getLineNumber();
      await lastValueFrom(this._inventoryManagementService.getInfoByStock(encStock, user, line)).then(
        (responseData: ResponseDataGetInfoByStock) => {
          if (!responseData.error && Object.keys(responseData.response).length > 0) {            
            this.formGroup.setValue(responseData.response);
          } else if (!responseData.error && Object.keys(responseData.response).length === 0) {
            this.resourcesService.openSnackBar(`Sin datos para mostrar.`);
            this._dialogReg.close(false);
          } else {
            this.resourcesService.openSnackBar(`${responseData.msg}`);
          }
        }, async (httpErrorResponse: HttpErrorResponse) => {
          let response = this.resourcesService.checkErrors(httpErrorResponse)
          if (response !== null && response.reload) {
            await this.getDetailsMultiCriteria();
          }
        }
      );
    } else if (this.detailsMultiCriteria.typeForm === 'search' && this.detailsMultiCriteria.infoForm !== null) {
      this.formGroup.controls['ID_STOCK'].setValue(this.detailsMultiCriteria.infoForm.ID_STOCK);
      this.formGroup.controls['CODIGO_EQUIPAMIENTO'].setValue(this.detailsMultiCriteria.infoForm.CODIGO_EQUIPAMIENTO);
      this.formGroup.controls['ID_UBICACION'].setValue(this.detailsMultiCriteria.infoForm.ID_UBICACION);

      let objFamily = null;
      if (this.detailsMultiCriteria.infoForm.FAMILIA !== null) {
        let idFamily = this.detailsMultiCriteria.infoForm.FAMILIA.ID_FAMILIA;
        let family = this.arrFamilies.find((dataFamilies:DataFamilies) => dataFamilies.ID_FAMILIA === idFamily);
        if (family !== undefined) {
          objFamily = family;
          this.arrSubfamilies = objFamily.SUBFAMILIAS;
          this.formGroup.controls['SUBFAMILIA'].enable();
        }
      }
      this.formGroup.controls['FAMILIA'].setValue(objFamily);

      let objSubfamily = null;
      if (this.detailsMultiCriteria.infoForm.SUBFAMILIA !== null && objFamily !== null) {
        let idSubfamily = this.detailsMultiCriteria.infoForm.SUBFAMILIA.ID_SUBFAMILIA;
        let subfamily = objFamily.SUBFAMILIAS.find((dataSubfamilies:DataSubfamilies) => dataSubfamilies.ID_SUBFAMILIA === idSubfamily);
        if (subfamily !== undefined) {
          objSubfamily = subfamily;
        }
      }
      this.formGroup.controls['SUBFAMILIA'].setValue(objSubfamily);

      this.formGroup.controls['MODELO'].setValue(this.detailsMultiCriteria.infoForm.MODELO);
      this.formGroup.controls['CODIGO_MODELO'].setValue(this.detailsMultiCriteria.infoForm.CODIGO_MODELO);
      this.formGroup.controls['ALMACEN'].setValue(this.detailsMultiCriteria.infoForm.ALMACEN);
      if (this.detailsMultiCriteria.infoForm.ALMACEN !== null) {
        await this.searchArea();
      }
      this.formGroup.controls['AREA'].setValue(this.detailsMultiCriteria.infoForm.AREA);
      if (this.detailsMultiCriteria.infoForm.AREA !== null) {
        await this.searchLevel();
      }
      this.formGroup.controls['NIVEL'].setValue(this.detailsMultiCriteria.infoForm.NIVEL);
      if (this.detailsMultiCriteria.infoForm.NIVEL !== null) {
        await this.searchZone();
      }
      this.formGroup.controls['ZONA'].setValue(this.detailsMultiCriteria.infoForm.ZONA);
      this.formGroup.controls['TIPO_ADQUISICION'].setValue(this.detailsMultiCriteria.infoForm.TIPO_ADQUISICION);
      this.formGroup.controls['NUMERO_PROVEEDOR'].setValue(this.detailsMultiCriteria.infoForm.NUMERO_PROVEEDOR);
      this.formGroup.controls['CODIGO_BARRAS'].setValue(this.detailsMultiCriteria.infoForm.CODIGO_BARRAS);
      this.formGroup.controls['FECHA_VENCIMIENTO'].setValue(this.detailsMultiCriteria.infoForm.FECHA_VENCIMIENTO);
      this.formGroup.controls['STOCK_MINIMO'].setValue(this.detailsMultiCriteria.infoForm.STOCK_MINIMO);
      this.formGroup.controls['STOCK_MAXIMO'].setValue(this.detailsMultiCriteria.infoForm.STOCK_MAXIMO);
      this.formGroup.controls['ESTADO'].setValue(this.detailsMultiCriteria.infoForm.ESTADO);
      this.formGroup.controls['CONSUMIBLE'].setValue(this.detailsMultiCriteria.infoForm.CONSUMIBLE);
      this.formGroup.controls['REPARABLE'].setValue(this.detailsMultiCriteria.infoForm.REPARABLE);
    }
  }

  private async searchArea() {
    this.searchingArea = true;
    this.isLoadingForm = true;
    const almacen = this.formGroup.controls['ALMACEN'].value;
    const encWarehouse: string = await this._encService.encrypt(almacen); 
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._inventoryManagementService.getAreaByWarehouse(encWarehouse, user, line)).then(
      async (responseData: ResponseDataGetAreaWarehouse) => {
        if (!responseData.error && responseData.response.length > 0) {
          this.arrAreas = responseData.response;
          this.formGroup.controls['AREA'].enable();
        } else if (!responseData.error && responseData.response.length === 0) {
          this.resourcesService.openSnackBar(`No existen áreas registradas para este almacén.`);
          this.formGroup.controls['AREA'].disable();
          this.formGroup.controls['AREA'].setValue('');
          this.formGroup.controls['NIVEL'].disable();
          this.formGroup.controls['NIVEL'].setValue('');
          this.formGroup.controls['ZONA'].disable();
          this.formGroup.controls['ZONA'].setValue('');
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.searchArea();
        }
      }
    );
    this.searchingArea = false;
    this.isLoadingForm = false;
  }

  private async searchLevel() {
    this.searchingLevel = true;
    this.isLoadingForm = true;
    const warehouse = this.formGroup.controls['ALMACEN'].value;
    const encWarehouse: string = await this._encService.encrypt(warehouse); 
    
    const area = this.formGroup.controls['AREA'].value;
    const encArea: string = await this._encService.encrypt(area);
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber(); 
    await lastValueFrom(this._inventoryManagementService.getLevelByAreaWarehouse(encWarehouse, encArea, user, line)).then(
      async (responseData: ResponseDataGetLevelAreaWarehouse) => {
        if (!responseData.error && responseData.response.length > 0) {
          this.arrLevel = responseData.response;
          this.formGroup.controls['NIVEL'].enable();
        } else if (!responseData.error && responseData.response.length === 0) {
          this.resourcesService.openSnackBar(`No existen niveles registrados para esta área.`);
          this.formGroup.controls['NIVEL'].disable();
          this.formGroup.controls['NIVEL'].setValue('');
          this.formGroup.controls['ZONA'].disable();
          this.formGroup.controls['ZONA'].setValue('');
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.searchLevel();
        }
      }
    );
    this.searchingLevel = false;
    this.isLoadingForm = false;
  }

  private async searchZone() {
    this.searchingZone = true;
    this.isLoadingForm = true;
    const warehouse = this.formGroup.controls['ALMACEN'].value;
    const encWarehouse: string = await this._encService.encrypt(warehouse); 

    const area = this.formGroup.controls['AREA'].value;
    const encArea: string = await this._encService.encrypt(area); 
    
    const nivel = this.formGroup.controls['NIVEL'].value;
    const encLevel: string = await this._encService.encrypt(nivel); 
    
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();

    await lastValueFrom(this._inventoryManagementService.getZoneByLevelAreaWarehouse(encWarehouse, encArea, encLevel, user, line)).then(
      async (responseData: ResponseDataGetZoneLevelAreaWarehouse) => {
        if (!responseData.error && responseData.response.length > 0) {
          this.arrZone = responseData.response;
          this.formGroup.controls['ZONA'].enable();
        } else if (!responseData.error && responseData.response.length === 0) {
          this.resourcesService.openSnackBar(`No existen zonas registradas para este nivel.`);
          this.formGroup.controls['ZONA'].disable();
          this.formGroup.controls['ZONA'].setValue('');
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.searchZone();
        }
      }
    );
    this.searchingZone = false;
    this.isLoadingForm = false;
  }

  public async search() {
    
    this._dialogReg.close({
      ID_STOCK: this.formGroup.controls['ID_STOCK'].value,
      CODIGO_EQUIPAMIENTO: this.formGroup.controls['CODIGO_EQUIPAMIENTO'].value,
      ID_UBICACION: this.formGroup.controls['ID_UBICACION'].value,
      FAMILIA: this.formGroup.controls['FAMILIA'].value,
      SUBFAMILIA: this.formGroup.controls['SUBFAMILIA'].value,
      MODELO: this.formGroup.controls['MODELO'].value,
      CODIGO_MODELO: this.formGroup.controls['CODIGO_MODELO'].value,
      ALMACEN: this.formGroup.controls['ALMACEN'].value,
      AREA: this.formGroup.controls['AREA'].value,
      NIVEL: this.formGroup.controls['NIVEL'].value,
      ZONA: this.formGroup.controls['ZONA'].value,
      TIPO_ADQUISICION: this.formGroup.controls['TIPO_ADQUISICION'].value,
      NUMERO_PROVEEDOR: this.formGroup.controls['NUMERO_PROVEEDOR'].value,
      CODIGO_BARRAS: this.formGroup.controls['CODIGO_BARRAS'].value,
      FECHA_VENCIMIENTO: this.formGroup.controls['FECHA_VENCIMIENTO'].value,
      STOCK_MINIMO: this.formGroup.controls['STOCK_MINIMO'].value,
      STOCK_MAXIMO: this.formGroup.controls['STOCK_MAXIMO'].value,
      ESTADO: this.formGroup.controls['ESTADO'].value,
      CONSUMIBLE: this.formGroup.controls['CONSUMIBLE'].value,
      REPARABLE: this.formGroup.controls['REPARABLE'].value,
    });
  }
}
