import { Component, Inject, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { GetInvoice, RequestInvoice, ResponseDataGetInvoice } from '../../../../../interfaces/acquisition-management/invoice.interface';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { GetDocumentOrder, RegisterFormDocument } from '../../../../../interfaces/acquisition-management/document-order.interface';
import { ResourcesService } from '../../../../../services/resources.service';
import { AcquisitionService } from '../../../../../services/acquisition-management/acquisition.service';
import { GdelService } from '../../../../../services/gdel.service';
import { InvoiceService } from '../../../../../services/acquisition-management/invoice.service';
import { EncService } from '../../../../../services/enc.service';
import { docClassification } from '../../../../../../environments/environment.prod';
import { lastValueFrom } from 'rxjs';
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-document-form',
    templateUrl: './document-form.component.html',
    styleUrl: './document-form.component.css',
    standalone: false
})
export class DocumentFormComponent implements OnInit {
  public isLoading: boolean;
  public isLoadingForm: boolean;
  public formGroup: FormGroup;
  public documentExtension: string;
  public fileDocument?: File;
  public titleForm: string;

  public nameButtonOtro: string; 
  public nameButtonPdf: string; 
  public nameButtonXml: string;

  public idOtro: string; 
  public idPdf: string; 
  public idXml: string;

  public arrInvoice: GetInvoice;

  public arrTypeFile: Array<{category:string,code:string}>;

  constructor(
    @Inject(MAT_DIALOG_DATA) public elementDialog: DataDialog,
    public resourcesService: ResourcesService,
    private _dialog: MatDialog,
    private _acquisitionService: AcquisitionService,
    private _dialogRef: MatDialogRef<any>,
    private _gdelService: GdelService,
    private _invoiceService: InvoiceService,
    private _encService: EncService,
  ) {
    this.formGroup = this.createFromGroup();
    this.documentExtension = '*';
    this.isLoading = false;
    this.isLoadingForm = false;
    this.titleForm = this.elementDialog.formData !== null ? 'Modificación de Documento' : 'Registro de Documento';
    this.arrTypeFile = docClassification;

    this.nameButtonOtro = 'Clic para subir un archivo';
    this.nameButtonPdf = 'Clic para subir la factura PDF';
    this.nameButtonXml = 'Clic para subir la factura XML';

    this.idOtro = '';
    this.idPdf = '';
    this.idXml = '';

    this.arrInvoice = {} as GetInvoice;
  }

  private createFromGroup(): FormGroup {
    return new FormGroup({
      ID_DOCUMENTO: new FormControl(''),
      TIPO_DOCUMENTO: new FormControl('', Validators.required),
      TIPO_ARCHIVO: new FormControl('', Validators.required),
      DOCUMENTOS: new FormControl('', Validators.required),
      DESCRIPCION: new FormControl(''),
    });
  }

  async ngOnInit() {
    this.isLoadingForm = true;
    this.isLoading = true;
    await this.setDataForm(this.elementDialog.formData);
    this.isLoadingForm = false;
    this.isLoading = false;

    this.formGroup.controls['TIPO_DOCUMENTO'].valueChanges.subscribe((typeDocument:string) => {
      if (typeDocument !== 'Otro') {
        this.formGroup.controls['TIPO_ARCHIVO'].setValue('FA');
        this.formGroup.controls['TIPO_ARCHIVO'].disable();
        this.documentExtension = '';
      } else {
        this.formGroup.controls['TIPO_ARCHIVO'].reset();
        this.formGroup.controls['TIPO_ARCHIVO'].enable();
        this.documentExtension = '';
      }
    });
  }

  private async setDataForm( formData?: GetDocumentOrder ) {
    if (formData !== null && formData !== undefined) { 
      this.formGroup.controls['ID_DOCUMENTO'].setValue( formData.DLSC_IDDO );
      this.formGroup.controls['TIPO_DOCUMENTO'].setValue( formData.DLSC_TIPO );
      this.formGroup.controls['TIPO_ARCHIVO'].setValue( formData.DLSC_TIAR );
      this.formGroup.controls['DESCRIPCION'].setValue( formData.DLSC_DESC === null ? '' : formData.DLSC_DESC );
      this.formGroup.controls['DOCUMENTOS'].setValue({ OTRO: 'NA', XML: 'NA', PDF: 'NA' });

      let codeDocument:string = await this._encService.decrypt(formData.DLSC_CODO);
      
      let arrCodeDocument: Array<string> = codeDocument.split('=');
      if (arrCodeDocument.length === 3) {
        if (formData.DLSC_TIAR === 'FA') {
          this.nameButtonPdf = arrCodeDocument[2];
        } else {
          this.nameButtonOtro = arrCodeDocument[2];
        }
      } else {
        this.resourcesService.openSnackBar(`Ocurrió un error al obtener el nombre del documento PDF.`)
      }

      if (formData.DLSC_IDFA !== null) {
        const user: string = this.resourcesService.getUser();
        const line: number = this.resourcesService.getLineNumber();
        const encIdInvoice:string = await this._encService.encrypt(formData.DLSC_IDFA.toString());
        await lastValueFrom(this._invoiceService.getInvoiceById(encIdInvoice, user, line)).then(
          async (responseData: ResponseDataGetInvoice) => {
            if (!responseData.error) {
              this.arrInvoice = responseData.response;
              let codeDocument:string = await this._encService.decrypt(this.arrInvoice.FALS_CODO);
              let arrCodeDocument: Array<string> = codeDocument.split('=');
              if (arrCodeDocument.length === 3) {
                this.nameButtonXml = arrCodeDocument[2];
              } else {
                this.resourcesService.openSnackBar(`Ocurrió un error al obtener el nombre del documento XML.`)
              }
            } else {
              this.resourcesService.openSnackBar(`${responseData.msg}`);
            }
          }, async (httpErrorResponse: HttpErrorResponse) => {
            let response = this.resourcesService.checkErrors(httpErrorResponse)
            if (response !== null && response.reload) {
              await this.setDataForm(formData);
            }
          }
        );
      }
    }
  }

  // Método para cargar la imagen
  public async loadDocument(event: any, typeFile:string) {
    const FILE: File = event.target.files[0];

    if (typeFile === 'OTRO') {
      this.nameButtonOtro = FILE.name || 'Clic para subir un archivo';
      if (this.idOtro !== '') {
        await this.deleteTempFile(this.idOtro);
      }
    } else if (typeFile === 'PDF') {
      this.nameButtonPdf = FILE.name || 'Clic para subir la factura PDF';
      if (this.idPdf !== '') {
        await this.deleteTempFile(this.idPdf);
      }
    } else if (typeFile === 'XML') {
      this.nameButtonXml = FILE.name || 'Clic para subir la factura XML';
      if (this.idXml !== '') {
        await this.deleteTempFile(this.idXml);
      }
    }

    await this.uploadTempFile(FILE, typeFile);
  }

  private async deleteTempFile(idArchivo:string) {
    this.isLoadingForm = true;
    this.resourcesService.openSnackBar(`Eliminando Archivo Anterior ...`);
    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(
      (responseData: ResponseDataUploadTempFile) => {
        if (!responseData.error) {
          this.resourcesService.openSnackBar(`¡Eliminación del archivo temporal exitosa!`);
        } 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;
  }

  private async uploadTempFile(invoice: File, typeDocument: string) {
    this.isLoadingForm = true;    
    this.resourcesService.openSnackBar(`Subiendo Archivo ...`);
    let myFormData = new FormData();
    myFormData.append('file', invoice!);
    myFormData.append('id_user', this.resourcesService.getUser());
    myFormData.append('linea', this.resourcesService.getLineNumber().toString());

    await lastValueFrom(this._gdelService.uploadTempFile(myFormData)).then(
      (responseDataUploadTempFile: ResponseDataUploadTempFile) => {
        if (!responseDataUploadTempFile.error) {
          if (typeDocument === 'OTRO') {
            this.idOtro = responseDataUploadTempFile.response.idArchivo;
            this.idPdf = '';
            this.idXml = '';
          } else if (typeDocument === 'PDF') {
            this.idOtro = ''
            this.idPdf = responseDataUploadTempFile.response.idArchivo;
          } else if (typeDocument === 'XML') {
            this.idOtro = ''
            this.idXml = responseDataUploadTempFile.response.idArchivo;
          }
            
          this.formGroup.controls['DOCUMENTOS'].setValue({
            OTRO: this.idOtro,
            XML: this.idPdf,
            PDF: this.idXml,
          });

          this.resourcesService.openSnackBar(`¡Archivo Subido!`);
        } else {
          this.resourcesService.openSnackBar(responseDataUploadTempFile.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.uploadTempFile(invoice, typeDocument);
        }
      }
    );
    this.isLoadingForm = false;
  }

  public async closeDialog() {
    if (this.idOtro !== '') {
      await this.deleteTempFile(this.idOtro);
      this.idOtro = '';
    }
    if (this.idPdf !== '') {
      await this.deleteTempFile(this.idPdf);
      this.idPdf = '';
    }
    if (this.idXml !== '') {
      await this.deleteTempFile(this.idXml);
      this.idXml = '';
    }

    this._dialogRef.close(false)
  }

  public alert() {
    this._dialog.open(AlertComponent, {
      data: {
        icon: 'warning',
        title: this.elementDialog.formData === null ? 'Registro de Documento' : 'Modificación de Documento',
        description: this.elementDialog.formData === null ? '¿Está seguro de registrar el documento?' : '¿Está seguro de modificar el documento?',
      }
    }).afterClosed().subscribe(async (result: boolean) => {
      if (result) {
        if (this.formGroup.controls['TIPO_ARCHIVO'].value === 'FA') {
          await this.compareInvoice();
        } else {
          if ( this.elementDialog.formData !== null ) {
            await this.updateDocumentOrder();
          } else {
            await this.registerDocumentOrder();
          }
        }
      }
    });
  }

  private async compareInvoice() {
    this.isLoadingForm = true;

    const requestInvoice:RequestInvoice = {
      IDARCHIVOPDF: this.idPdf === '' ? null : this.idPdf,
      IDARCHIVOXML: this.idXml === '' ? null : this.idXml,
      TYPE_INVOICE: this.formGroup.controls['TIPO_DOCUMENTO'].value,
      DESCRIPTION: this.formGroup.controls['DESCRIPCION'].value,
      ID_DOCUMENT: this.elementDialog.formData !== null && this.elementDialog.formData !== undefined ? this.elementDialog.formData.DLSC_IDDO : null,
      USER: this.resourcesService.getUser(),
      LINE_NUMBER: this.resourcesService.getLineNumber(),
      REQUEST_LINE: this.elementDialog.lineNumber.toString(),
    }

    await lastValueFrom(this._invoiceService.compareInvoice(requestInvoice)).then(
      (responseData: ResponseData) => {
        if (!responseData.error) {
          this.resourcesService.openSnackBar(`¡La comparación de factura ha sido exitosa!`);
          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.compareInvoice();
        }
      }
    );

    this.isLoadingForm = false;
  }

  private async updateDocumentOrder() {    
    const requestDocument:RegisterFormDocument = this.generateObjectRequest();
    await lastValueFrom(this._acquisitionService.updateDocumentOrder( requestDocument )).then(
      (responseData: ResponseData) => {
        if ( !responseData.error ) {
          this.resourcesService.openSnackBar('¡Modificación de Documento 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.updateDocumentOrder();
        }
      }
    );
  }

  private generateObjectRequest(): RegisterFormDocument{
    let documentos = this.idOtro;
    let tipoDocumento = this.formGroup.controls['TIPO_DOCUMENTO'].value;
    let tipoArchivo = this.formGroup.controls['TIPO_ARCHIVO'].value;
    let descripcion = this.formGroup.controls['DESCRIPCION'].value;
    if (descripcion != null || descripcion != '') {
      descripcion = descripcion.toString().trim();
    }

    let usuario:string = this.resourcesService.getUser();
    let numeroLinea:number = this.resourcesService.getLineNumber();
    
    return {
      LINEA_SOLICITUD: this.elementDialog.lineNumber,
      ID_DOCUMENTO: this.elementDialog.formData !== null && this.elementDialog.formData !== undefined ? this.elementDialog.formData.DLSC_IDDO : null,
      TIPO_DOCUMENTO: tipoDocumento,
      TIPO_ARCHIVO: tipoArchivo,
      DOCUMENTO: this.idOtro,
      DESCRIPCION: descripcion,
      USUARIO: usuario,
      NUMERO_LINEA: numeroLinea,
    }
  }

  private async registerDocumentOrder() {    
    const requestDocument:RegisterFormDocument = this.generateObjectRequest();
    await lastValueFrom(this._acquisitionService.registerDocumentOrder( requestDocument )).then(
      (responseData: ResponseData) => {
        if ( !responseData.error ) {
          this.resourcesService.openSnackBar('¡Registro de Documento 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.registerDocumentOrder();
        }
      }
    );
  }
}

export interface DataDialog{ 
  orden: string;
  lineNumber: string;
  formData?: GetDocumentOrder;
}