import { Component, Inject, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { FileSelected } from '../../../../../interfaces/upload-files.interface';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { ResourcesService } from '../../../../../services/resources.service';
import { AcquisitionService } from '../../../../../services/acquisition-management/acquisition.service';
import { GdelService } from '../../../../../services/gdel.service';
import { lastValueFrom } from 'rxjs';
import { ResponseDataLastState } from '../../../../../interfaces/acquisition-management/order.interface';
import { HttpErrorResponse } from '@angular/common/http';
import { ResponseDataUploadTempFile } from '../../../../../interfaces/gdel.interface';
import { AlertComponent } from '../../../../resources/dialogs/alert/alert.component';
import { ResponseData } from '../../../../../interfaces/response-data';

@Component({
    selector: 'app-add-state-order',
    templateUrl: './add-state-order.component.html',
    styleUrl: './add-state-order.component.css',
    standalone: false
})
export class AddStateOrderComponent implements OnInit {
  public arrStatesOrders: Array<string>;
  public formGroup: FormGroup;
  
  public isLoading: boolean;
  public isLoadingForm: boolean;

  public arrFileSelected: Array<FileSelected>;

  constructor(
    @Inject(MAT_DIALOG_DATA) public orderNumber: string,
    public resourcesService: ResourcesService,
    private _dialog: MatDialog,
    private _acquisitionService: AcquisitionService,
    private _dialogRef: MatDialogRef<AddStateOrderComponent>,
    private _gdelService: GdelService,
  ) {
    this.arrStatesOrders = ['Editado','En curso','Recibido Parcial','Recibido','Facturado','Anulado'];
    this.formGroup = this.createFormGroup();

    this.arrFileSelected = [];
    this.isLoading = false;
    this.isLoadingForm = false;
  }

  private createFormGroup() {
    return new FormGroup({
      'ESTADO': new FormControl('', Validators.required),
      'DESCRIPCION': new FormControl('', Validators.required),
      'EVIDENCIA': new FormControl('', Validators.required),
      'PORCENTAJE': new FormControl('', [Validators.required, Validators.max(100)]),
      'NUMERO_ORDEN': new FormControl(this.orderNumber, Validators.required),
    })
  }

  async ngOnInit() {
    this.isLoadingForm = true;
    this.isLoading = true;
    await this.getLastState();
    this.isLoadingForm = false;
    this.isLoading = false;
  }

  private async getLastState() {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._acquisitionService.getLastSateOrder(this.orderNumber, user, line)).then(
      (responseData: ResponseDataLastState) => {
        if (!responseData.error) {
          this.formGroup.controls['PORCENTAJE'].setValue(responseData.response.PORCENTAJE_ENTREGA);
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
          this._dialogRef.close(false);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getLastState();
        }
        this._dialogRef.close(false);
      }
    );
  }

  public formatLabel = (value: number) => `${value}%`;

  public async loadImg(event: any) {
    this.isLoadingForm = true;
    let arrFiles: Array<File> = Array.from(event.target.files);

    if (arrFiles.length > 1) {
      this.resourcesService.openSnackBar(`Analizando los ${arrFiles.length} archivos seleccionados.`)
    } else {
      this.resourcesService.openSnackBar(`Analizando el archivo seleccionado`);
    }
    
    let arrIdFile: Array<string> = [];

    await Promise.all(
      arrFiles.map(async (file:File) => {
        var myFormData = new FormData();
        myFormData.append('file', file);
        myFormData.append('id_user', this.resourcesService.getUser());
        myFormData.append('linea', this.resourcesService.getLineNumber().toString());

        await lastValueFrom(this._gdelService.uploadTempFile(myFormData )).then(
          async (responseData: ResponseDataUploadTempFile) => {
            if (!responseData.error) {            
              this.arrFileSelected.push({
                id: responseData.response.idArchivo, 
                file: file,
                view: URL.createObjectURL(file),
                size: this.resourcesService.formatBytes(file.size),
              });
              arrIdFile.push(responseData.response.idArchivo);
            } else {
              this.resourcesService.openSnackBar(`${responseData.msg}`);
            }
          }, async (httpErrorResponse: HttpErrorResponse) => {
            let response = this.resourcesService.checkErrors(httpErrorResponse)
            if (response !== null && response.reload) {
              await this.loadImg(event);
            }
          }
        );
      })
    );

    if (arrIdFile.length != arrFiles.length) {
      this.resourcesService.openSnackBar(`Ocurrió un error con algún archivo, eliminando los archivos.`);
      await Promise.all(
        arrIdFile.map(async (idFile:string) => {
          await this.deleteTempFile(idFile);
        })
      );
      this.arrFileSelected = this.arrFileSelected.filter((selected:FileSelected) => !arrIdFile.includes(selected.id));

    } else {
      this.resourcesService.openSnackBar(`¡Archivos Analizados Exitosamente!`);
      const arrId:Array<string> = this.arrFileSelected.map(( fileSelected:FileSelected) => fileSelected.id);
      this.formGroup.controls['EVIDENCIA'].setValue(arrId);

    }
    this.isLoadingForm = false;
  }

  private async deleteTempFile(idArchivo:string) {
    this.isLoadingForm = true;
    this.resourcesService.openSnackBar(`Eliminando archivo, espere un momento`);
    var myFormData = new FormData();
    myFormData.append('id_file', idArchivo);
    myFormData.append('id_user', this.resourcesService.getUser());
    myFormData.append('linea', this.resourcesService.getLineNumber().toString());

    await lastValueFrom(this._gdelService.deleteTempFile(myFormData)).then(
      async (responseData: ResponseDataUploadTempFile) => {
        if (!responseData.error) {
          this.resourcesService.openSnackBar(`¡Eliminación del archivo temporal exitosa!`);
          this.arrFileSelected = await Promise.all(this.arrFileSelected.filter((selected:FileSelected) => selected.id !== idArchivo));
          const arrId:Array<string> = await Promise.all(this.arrFileSelected.map(( fileSelected:FileSelected) => fileSelected.id));
          this.formGroup.controls['EVIDENCIA'].setValue(arrId);
        } else {
          this.resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.deleteTempFile(idArchivo);
        }
      }
    );
    this.isLoadingForm = false;
  }

  // Método para ejecutar una alerta
  public async alert(typeAlert:string, idFile?:string) {
    this.isLoadingForm = true;
    if (typeAlert === 'DELETE_TEMP') {
      this._dialog.open(AlertComponent, {
        data: {
          icon: "warning",
          title: "Eliminar Archivo",
          description: "¿Está seguro de eliminar el archivo seleccionado?"
        },
        disableClose: true,
      }).afterClosed().subscribe(async (result) => {
        if (result) {
          await this.deleteTempFile(idFile!);
        } 
      });
    } else if (typeAlert === 'UPDATE') {
      this._dialog.open(AlertComponent, {
        data: {
          icon: "warning",
          title: "Modificar Estado",
          description: "¿Está seguro de modificar el estado de la orden de compra?"
        },
        disableClose: true,
      }).afterClosed().subscribe(async (result) => {
        if (result) {
          await this.updateStateOrder();
        } 
      });
    }
    this.isLoadingForm = false;
  }

  public async updateStateOrder() {
    this.isLoadingForm = true;
    this.createObjectRequest();
    await lastValueFrom(this._acquisitionService.updateStateHistory( this.createObjectRequest() )).then(
      (responseData: ResponseData) => {
        if ( !responseData.error ) {
          this.resourcesService.openSnackBar('¡Modificación de Estado Exitoso!');
          this._dialogRef.close(true);
        } else {
          this.resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.updateStateOrder();
        }
      }
    );
    this.isLoadingForm = false;
  }

  private createObjectRequest():CreateObjectRequest {
    
    let estado:string = this.formGroup.controls['ESTADO'].value.toString();
    let descripcion:string = this.formGroup.controls['DESCRIPCION'].value.toString().trim();
    let evidencia:Array<string> = this.formGroup.controls['EVIDENCIA'].value;
    let porcentaje:string = this.formGroup.controls['PORCENTAJE'].value.toString();
    let numero_orden:string = this.formGroup.controls['NUMERO_ORDEN'].value.toString().trim();
    
    const createObjectRequest: CreateObjectRequest = {
      ESTADO: estado,
      DESCRIPCION: descripcion,
      EVIDENCIA: evidencia,
      PORCENTAJE: porcentaje,
      NUMERO_ORDEN: numero_orden,
      USUARIO: this.resourcesService.getUser(),
      NUMERO_LINEA: this.resourcesService.getLineNumber()
    };
    
    return createObjectRequest;
  }

  public async close() {
    await Promise.all(
      this.arrFileSelected.map(async (fileSelected:FileSelected) => {
        await this.deleteTempFile(fileSelected.id);
      })
    );
    this._dialogRef.close(false);
  }
}

export interface CreateObjectRequest {
  ESTADO: string;
  DESCRIPCION: string;
  EVIDENCIA: Array<string>;
  PORCENTAJE: string;
  NUMERO_ORDEN: string;
  USUARIO: string;
  NUMERO_LINEA: number;
}
