// Angular Core
import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
import { FormGroup, FormGroupDirective } from '@angular/forms';

// RxJs
import { Subscription, catchError, throwError } from 'rxjs';

// Services
import { AccountInfoService } from 'src/app/services/accountInfo/account-info.service';
import { MainSettingsService } from 'src/app/services/mainSettings/main-settings.service';

// Interfaces
import { DocumentConfig, ModalConfig, saveMainSettingsInterface, uploadDocument } from 'src/app/interfaces/common-interfaces';
import { SuppliersMainSettingsInterface } from 'src/app/interfaces/supplier/suppliers-main-settings-interface';

// Third Party
import { NgbModal, NgbModalConfig, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { UtilitiesService } from 'src/app/services/utilities/utilities.service';

@Component({
  standalone: false,
  selector: 'app-document-main-settings',
  templateUrl: './document-main-settings.component.html',
  styleUrls: ['./document-main-settings.component.scss']
})
export class DocumentMainSettingsComponent implements OnInit, OnDestroy {

  @Input() supplierData!:SuppliersMainSettingsInterface['data']['supplierData'];
  @Input() formGroupName!:string;

  @Output() updateSupplierData = new EventEmitter();

  @ViewChild('deleteConfirmModal') deleteConfirmModal !: ElementRef;

  /**
  * 
  * @type FormData
  */
  formdata:any = new FormData();
  removeDoc!: string;

  
  /**
  * Upload-document directive related variables
  */
  deaParamName: string = '';
  stateParamName: string = '';
  showMsg: boolean = false;
  showErrMsg: boolean = false;
  uploadedDocs: any = [];
  isReadyToValidate: boolean = false;

  documentMainSettingsForm!: FormGroup;
  achAuthFormConfig: DocumentConfig = {
    param: 'ach_authorization_form',
    autoUpload: true,
    inputClass: 'ms-custom-file-input',
    error: false,
    successTxtCls: 'document-upload-success-txt',
    accFileTypes: []
  };
  suppAppDocConfig: DocumentConfig = {
    param: 'supplier_application_document',
    autoUpload: true,
    inputClass: 'ms-custom-file-input',
    error: false,
    successTxtCls: 'document-upload-success-txt',
    accFileTypes: []
  };
  credCardAuthFormConfig: DocumentConfig = {
    param: 'credit_card_authorization_form',
    autoUpload: true,
    inputClass: 'ms-custom-file-input',
    error: false,
    successTxtCls: 'document-upload-success-txt',
    errorMsg: '',
    accFileTypes: []
  };
  vawdAccredLetterConfig: DocumentConfig = {
    param: 'vawd_accred_letter',
    autoUpload: true,
    inputClass: 'ms-custom-file-input',
    error: false,
    successTxtCls: 'document-upload-success-txt',
    errorMsg: '',
    accFileTypes: []
  };
  ctrlSubstanceFormConfig: DocumentConfig = {
    param: 'supplier_controlled_substance_form',
    autoUpload: true,
    inputClass: 'ms-custom-file-input',
    error: false,
    successTxtCls: 'document-upload-success-txt',
    errorMsg: '',
    accFileTypes: []
  };

  constructor(
    private accountInfo: AccountInfoService,
    private mainSettingsService: MainSettingsService,
    private modalService: NgbModal,
    private rootForm:FormGroupDirective,
    private ngbModalconfig: NgbModalConfig,
    private utilities: UtilitiesService
  ) {
    this.ngbModalconfig.backdrop = 'static';
    this.ngbModalconfig.keyboard = false;
   }

  ngOnInit(): void {
    this.documentMainSettingsForm = this.rootForm.control.get(this.formGroupName) as FormGroup;
    this.documentMainSettingsFormUpdate();
  }

  get documentMainSettingsFormData() { return this.documentMainSettingsForm.controls; }

  documentMainSettingsFormUpdate() {
    setTimeout(() => {
        this.documentMainSettingsForm.patchValue({
            supplier_application_document : this.supplierData.supplier_application_document,
            echosign_signatureType : this.supplierData.echosign_signatureType,
            ach_authorization_form : this.supplierData.ach_authorization_form,
            credit_card_authorization_form : this.supplierData.credit_card_authorization_form,
            is_credit_app_doc_reqd : this.supplierData.is_credit_app_doc_reqd,
            is_payment_info_enabled : this.supplierData.is_payment_info_enabled,
            renew_app_timeframe : this.supplierData.renew_app_timeframe,
            vawd_accred_letter : this.supplierData.vawd_accred_letter,
            supplier_controlled_substance_form : this.supplierData.supplier_controlled_substance_form,
            require_cs_app : this.supplierData.require_cs_app,
            cs_esign_type : this.supplierData.cs_esign_type,
            resale_cert_required : this.supplierData.resale_cert_required,
    })}, 2000);
  }

  /**
  * Function to get uploaded files
  * @param {type} $files
  * @param {type} type
  * @returns {undefined}
  */
  uploadFile(event:any, type:string) {
    const files = Object.keys(event.target.files).map(key => ({key, value: event.target.files[key]}));
    files.forEach((value:any, key:number) => {
      this.formdata.append(type, value.value);
    });
    this.uploadDocument(type);
  };

  message!: string;

  /**
  * 
  * @returns {undefined}
  */
  uploadDocumentSubscribe!:Subscription;
  uploadDocument(type:string) {
    this.supplierData[type] = 0;
    this.uploadDocumentSubscribe = this.accountInfo.uploadDocument(this.formdata)
        .pipe(
          catchError(() => {
            return throwError(() => new Error('ups sommething happend'));
          })
        )
        .subscribe({
          next: (res: uploadDocument) => {
            this.message = res.data.document + " uploaded successfully";
            this.supplierData[type] = 1;
            var tempFormData = new FormData();

            this.formdata.forEach((value:any, key:any) => {
              if(key !== type) {
                tempFormData.append(key, value);
              }
            });
            this.formdata = tempFormData;
          },
          error: (err) => {
            var tempFormData = new FormData();
            this.formdata.forEach((value:any, key:any) => {
              if (key !== type) {
                tempFormData.append(key, value);
              }
            });
            this.formdata = tempFormData;
            this.accountInfo.errorCallBack(err);
          },
          complete: () => { },
        })
  };

  /**
  * Function to remove document
  * @param {type} doc
  * @returns {undefined}
  */
  saveMainSettingsSubscribe!:Subscription;
  removeDocument(doc:string) {
    var DataSet = {"remove_doc":doc}
    this.saveMainSettingsSubscribe = this.mainSettingsService.saveMainSettings(DataSet)
      .pipe(
        catchError(() => {
          return throwError(() => new Error('ups sommething happend'));
        })
      )
      .subscribe({
        next: (res: saveMainSettingsInterface) => {
          this.supplierData[doc] = 0;
          this.confirmModalClose();
        },
        error: (err) => {
          this.mainSettingsService.errorCallBack(err);
        },
        complete: () => { },
      })
  };

  /*
  * Private Property for base modal config for delete confirmation modal
  */
  deleteConfirmModalConfig:ModalConfig = {
    showHeader: true,
    title: ""
  };

  /**
   * Private method to show the document delete confirmation modal
   * @returns null
   */
  deleteConfirmModalSub!:NgbModalRef;
  showConfirmModal(doc:string) {
      this.removeDoc = doc;
      this.deleteConfirmModalConfig.title = "";
      this.deleteConfirmModalSub = this.modalService.open(this.deleteConfirmModal, {size: 'sm'});
  };
  
  /*
  * Method to close confirmation modal
  */
  confirmModalClose () {
      this.deleteConfirmModalSub.close();
  };

  /**
   * Function to emit the updateSupplier Data to listen that emitter into the parent component
   * @param {string | boolean | number} supplierData
   * @param {string} settingsElementName
   */
    callUpdateSupplierDataFunc(supplierData:string | boolean | number, settingsElementName:string){
      const booleanValuesToUpdate = [
        "is_credit_app_doc_reqd",
        "is_payment_info_enabled"
      ]
      Object.keys(this.documentMainSettingsForm.controls).forEach(controlName => {
        this.supplierData[controlName] = this.documentMainSettingsForm.controls[controlName].value;
      });
      supplierData = this.documentMainSettingsForm.get(settingsElementName)?.value;
      if(booleanValuesToUpdate.includes(settingsElementName)){
        supplierData = supplierData ? 0 : 1;
      }
      const updateSupplierDataToEmit = {
        supplierData: supplierData,
        settingsElementName: settingsElementName,
      }

      this.updateSupplierData.emit(updateSupplierDataToEmit);
    }

    /**
     * This method enable file status message with the given message{success/error} based on the file upload status.
     * @param string statusMsg
     * @param bool status
     * @param string docType
     * @returns {undefined}
     * Note: Upload-document directive related function
     */
    setFileStatusMsg(statusMsg: string, status: boolean, docType: string) {
      this.message = statusMsg;
      status ? this.showMsg = true : this.showErrMsg = true;
      // if(status === true) {
      //     this.showMsg = true;
      // } else {
      //     this.showErrMsg = true;
      // }
    };

    /**
     * This method will set the file validation message.
     * @param string param
     * @param bool status
     * @returns {undefined}
     * Note: Upload-document directive related function
     */
    supplierAppDoc!:string;
    resaleDocParamName!:string;
    setFileValidationMsg(param: string, status: boolean) {
      if (param === 'supplier_application_document') {
          if (status) {
              this.supplierAppDoc = param;
          } else {
              this.supplierAppDoc = '';
          }
      } else if(param === 'state_medical_license_document') {
          if (status) {
              this.stateParamName = param;
          } else {
              this.stateParamName = '';
          }
      } else if(param === 'resale_application_document') {
          if (status) {
              this.resaleDocParamName = param;
          } else {
              this.resaleDocParamName = '';
          }
      }
    };

    /**
     * Update document config with the object sent by upload document directive
     * after the upload document process is complete.
     * @param docConfig 
     */
    updateDocConfig(docConfig: DocumentConfig) {
      switch (docConfig.param) {
        case 'ach_authorization_form':
          this.utilities.merge(this.achAuthFormConfig, docConfig);
          break;
        case 'supplier_application_document':
          this.utilities.merge(this.suppAppDocConfig, docConfig);
          break;
        case 'credit_card_authorization_form':
          this.utilities.merge(this.credCardAuthFormConfig, docConfig);
          break;
        case 'vawd_accred_letter':
          this.utilities.merge(this.vawdAccredLetterConfig, docConfig);
          break;
        case 'supplier_controlled_substance_form':
          this.utilities.merge(this.ctrlSubstanceFormConfig, docConfig);
          break;
      }
      this.supplierData[docConfig.param] = 1;
    }

    ngOnDestroy(){
      this.saveMainSettingsSubscribe?.unsubscribe();
      this.uploadDocumentSubscribe?.unsubscribe();
    }

}
