import { Component, Inject, OnInit } from '@angular/core';
import { PreventiveWorkOrdersActive, PreventiveWorkOrdersActiveResponse } from '../../../../../interfaces/preventive-work-orders-active.interface';
import { CorrectiveWorkOrdersListItem, CorrectiveWorkOrdersListResponse } from '../../../../../interfaces/corrective-maintenance.interface';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { DispatchData, ResponseDataDispatch } from '../../../../../interfaces/acquisition-management/dispatch.interface';
import { lastValueFrom, map, Observable, startWith } from 'rxjs';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { RequestLines, RequestOrder } from '../../../../../interfaces/acquisition-management/order.interface';
import { ResourcesService, ResponseData } from '../../../../../services/resources.service';
import { PreventiveMaintenanceService } from '../../../../../services/preventive-maintenance.service';
import { CorrectiveMaintenanceService } from '../../../../../services/corrective-maintenance.service';
import { EncService } from '../../../../../services/enc.service';
import { Router } from '@angular/router';
import { AcquisitionService } from '../../../../../services/acquisition-management/acquisition.service';
import { DispatchService } from '../../../../../services/acquisition-management/dispatch.service';
import { HttpErrorResponse } from '@angular/common/http';
import { AlertComponent } from '../../../../resources/dialogs/alert/alert.component';

@Component({
    selector: 'app-form-purchase-line',
    templateUrl: './form-purchase-line.component.html',
    styleUrl: './form-purchase-line.component.css',
    standalone: false
})
export class FormPurchaseLineComponent implements OnInit {
  public arrPreventiveMaintenance: Array<PreventiveWorkOrdersActive>;
  public preventiveMaintenanceStr: Array<string>;
  public arrCorrectiveMaintenance: Array<CorrectiveWorkOrdersListItem>;
  public correctiveMaintenanceStr: Array<string>;
  public arrProject: Array<any>;
  public formGroup: FormGroup;
  public arrDispatch: Array<DispatchData>;
  
  public isLoading: boolean;
  public isLoadingForm: boolean;

  public filteredPreventiveMaintenance!: Observable<Array<string>>;
  public filteredCorrectiveMaintenance!: Observable<Array<string>>;

  constructor(
    @Inject(MAT_DIALOG_DATA) public requestLines: RequestLines,
    public resourcesService: ResourcesService,
    private _preventiveMaintenanceService: PreventiveMaintenanceService,
    private _correctiveMaintenanceService: CorrectiveMaintenanceService,
    private _dialogRef: MatDialogRef<boolean>,
    private _encService: EncService,
    private _router: Router,
    private _dialog: MatDialog,
    private _acquisitionService: AcquisitionService,
    private _distpachService: DispatchService,
  ) {
    this.arrPreventiveMaintenance = [];
    this.arrCorrectiveMaintenance = [];
    this.preventiveMaintenanceStr = [];
    this.correctiveMaintenanceStr = [];

    this.arrProject = [];
    this.arrDispatch = [];

    this.formGroup = this.createFormGroup();
    this.isLoading = false;
    this.isLoadingForm = false;
  }

  private createFormGroup() {
    return new FormGroup({
      PROPOSITO: new FormControl( 'NA', Validators.required),
      ID_MANT_PREV: new FormControl({ value: '', disabled: true }),
      ID_MANT_CORR: new FormControl({ value: '', disabled: true }),
      DESPACHO: new FormControl( '', Validators.required),
    });
  }

  async ngOnInit() {
    this.isLoading = true;
    this.isLoadingForm = true;
    await this.getPreventiveMaintenance();
    await this.getCorrectiveMaintenance();
    await this.getDispatchActive();
    this.isLoading = false;
    this.isLoadingForm = false;


    this.formGroup.controls['PROPOSITO'].valueChanges.subscribe((proposito) => {
      if (proposito === 'MANT-PREV') {
        this.formGroup.controls['ID_MANT_PREV'].enable();
        this.formGroup.controls['ID_MANT_PREV'].setValidators(Validators.required);
        this.formGroup.controls['ID_MANT_CORR'].setValue('');
        this.formGroup.controls['ID_MANT_CORR'].disable();
        this.formGroup.controls['ID_MANT_CORR'].clearValidators();
        this.formGroup.controls['ID_MANT_PREV'].updateValueAndValidity();
        this.formGroup.controls['ID_MANT_CORR'].updateValueAndValidity();
      } else if (proposito === 'MANT-CORR') {
        this.formGroup.controls['ID_MANT_CORR'].enable();
        this.formGroup.controls['ID_MANT_CORR'].setValidators(Validators.required);
        this.formGroup.controls['ID_MANT_PREV'].disable();
        this.formGroup.controls['ID_MANT_PREV'].setValue('');
        this.formGroup.controls['ID_MANT_PREV'].clearValidators();
        this.formGroup.controls['ID_MANT_PREV'].updateValueAndValidity();
        this.formGroup.controls['ID_MANT_CORR'].updateValueAndValidity();
      } else if (proposito === 'NA') {
        this.formGroup.controls['ID_MANT_PREV'].disable();
        this.formGroup.controls['ID_MANT_CORR'].disable();
        this.formGroup.controls['ID_MANT_PREV'].setValue('');
        this.formGroup.controls['ID_MANT_CORR'].setValue('');
        this.formGroup.controls['ID_MANT_PREV'].clearValidators();
        this.formGroup.controls['ID_MANT_CORR'].clearValidators();
        this.formGroup.controls['ID_MANT_PREV'].updateValueAndValidity();
        this.formGroup.controls['ID_MANT_CORR'].updateValueAndValidity();
      }
    });

    this.filteredPreventiveMaintenance = this.formGroup.controls['ID_MANT_PREV'].valueChanges.pipe(
      startWith(''),
      map((value) => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.preventiveMaintenanceStr.filter((item) => item.toLowerCase().includes(filterValue));
      })
    )
    this.filteredCorrectiveMaintenance = this.formGroup.controls['ID_MANT_CORR'].valueChanges.pipe(
      startWith(''),
      map((value) => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.correctiveMaintenanceStr.filter((item) => item.toLowerCase().includes(filterValue));
      })
    )
  }

  private async getPreventiveMaintenance() {
    const idUser:string = this.resourcesService.getUser();
    const line:number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._preventiveMaintenanceService.getActiveWorkOrders(idUser, line)).then(
      (responseData: PreventiveWorkOrdersActiveResponse) => {
        if ( !responseData.error ) {
          this.arrPreventiveMaintenance = responseData.response;
          this.preventiveMaintenanceStr = this.arrPreventiveMaintenance.map(
            (preventiveWorkOrdersActive: PreventiveWorkOrdersActive) => `#${ preventiveWorkOrdersActive.IDORDEN }` )
        } else {
          this.resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getPreventiveMaintenance();
        }
      }
    );
  }

  private async getCorrectiveMaintenance() {
    const idUser:string = this.resourcesService.getUser();
    const line:number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._correctiveMaintenanceService.getWorkOrders(idUser, line)).then(
      async (responseData: CorrectiveWorkOrdersListResponse) => {
        if ( !responseData.error ) {
          this.arrCorrectiveMaintenance = responseData.response;
          this.correctiveMaintenanceStr = [];
          await Promise.all(
            this.arrCorrectiveMaintenance.map(async (correctiveWorkOrdersListItem: CorrectiveWorkOrdersListItem) => {
              let decOrder = await this._encService.decrypt(correctiveWorkOrdersListItem.ID_ORDEN);
              this.correctiveMaintenanceStr.push(`#${decOrder}`);
            })
          )
        } else {
          this.resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getCorrectiveMaintenance();
        }
      }
    );
  }

  private async getDispatchActive() {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._distpachService.getDispatchActive(user, line)).then(
      (responseData: ResponseDataDispatch) => {
        if ( !responseData.error ) {
          if (responseData.response.length === 0) {
            this.resourcesService.openSnackBar('No hay despachos registrados en SAM');
            this._dialogRef.close(false);
          }
          this.arrDispatch = responseData.response;
          console.log(this.arrDispatch);
          
        } else {
          this.resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getDispatchActive();
        }
      }
    );
  }

  public alert() {
    this._dialog.open(AlertComponent, {
      data: {
        title: `Confirmación`,
        description: `¿Está seguro de registrar la orden de compra?`,
        icon: `warning`,
      }
    }).afterClosed().subscribe((result) => {
      if (result) {
        this.createOrder()
      }
    });
  }

  private async createOrder() {
    this.isLoadingForm = true;
    const objRequestOrder: RequestOrder | false = this.createRequestOrder();
    if (objRequestOrder !== false) {
      await lastValueFrom(this._acquisitionService.generateOrders(objRequestOrder)).then(
        (responseData: ResponseData) => {
          if (!responseData.error) {
            this.resourcesService.openSnackBar(`¡Registro de Orden Exitosa!`);
            this._router.navigate(['/sam/GEAD/ADQU/SEPE']);
            this._dialogRef.close(true);
          } else {
            this.resourcesService.openSnackBar(`${responseData.error}`);
          }
        }, async (httpErrorResponse: HttpErrorResponse) => {
          let response = this.resourcesService.checkErrors(httpErrorResponse)
          if (response !== null && response.reload) {
            await this.createOrder();
          }
        }
      );
    }
    this.isLoadingForm = false;
  }

  private createRequestOrder(): RequestOrder | false {

    let numeroSolicitud = this.requestLines.ID_LINEA_SOLICITUD.toString().trim();
    
    let despacho = this.formGroup.controls['DESPACHO'].value;
    despacho = despacho.toString().trim();

    let proposito = this.formGroup.controls['PROPOSITO'].value;

    let idMantPrev = this.formGroup.controls['ID_MANT_PREV'].value;

    let idMantCorr = this.formGroup.controls['ID_MANT_CORR'].value;

    if (proposito === 'MANT-PREV' && idMantPrev !== null && idMantPrev !== '' && idMantPrev !== undefined) {
      idMantPrev = idMantPrev.trim();
      idMantPrev = idMantPrev.replace('#', '');
      idMantCorr = null;
    } else if (proposito === 'MANT-CORR' && idMantCorr !== null && idMantCorr !== '' && idMantCorr !== undefined) {
      idMantCorr = idMantCorr.trim();
      idMantCorr = idMantCorr.replace('#', '');
      idMantPrev = null;
    } else if (proposito === 'NA') {
      idMantCorr = null;
      idMantPrev = null;
    } else {
      this.resourcesService.openSnackBar(`Ocurrió un error al verificar el propósito.`)
      return false;
    }

    let requestOrder:RequestOrder = {
      NUMERO_SOLICITUD: numeroSolicitud,
      DESPACHO: despacho,
      PROPOSITO: proposito,
      ID_MANT_PREV: idMantPrev,
      ID_MANT_CORR: idMantCorr,
      NUMERO_LINEA: this.resourcesService.getLineNumber(),
      USUARIO: this.resourcesService.getUser(),
    }
    return requestOrder;
  }
}
