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

// Interfaces
import { creditTermsInfoInterface, getPaymentTypesInfoInterface } from 'src/app/interfaces/common-interfaces';
import { UpdateSupplierDataInterface } from 'src/app/interfaces/supplier/bulk-upload-settings';
import { SaveSupplierEmitterInterface } from 'src/app/interfaces/supplier/credit-settings-interface';
import { SuppliersMainSettingsInterface } from 'src/app/interfaces/supplier/suppliers-main-settings-interface';

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

  @Input() supplierData!:SuppliersMainSettingsInterface['data']['supplierData'];
  @Input() paymentTypes!:getPaymentTypesInfoInterface['data'];
  @Input() ptypeSelected!:number[];
  @Input() formGroupName!:string;
  @Input() creditTerms!:creditTermsInfoInterface['data'];

  @Output() updateSupplierData = new EventEmitter();
  @Output() updateFopValidation = new EventEmitter()
  @Output() saveSupplierPtype = new EventEmitter<SaveSupplierEmitterInterface>()

  isDisabled!:boolean;
  hascreditLimit: boolean | number | undefined;
  creditSettingsForm!: FormGroup;
  isChecked!:boolean;
  additionalChargeAmtError: string = '';
  fopValidationFlag: boolean = false;

  constructor(
    private rootForm:FormGroupDirective,
  ) { }

  ngOnInit(): void {
    if (this.supplierData.default_credit_limit === -1) {
      this.isDisabled = true;
    } else if ((this.supplierData.default_credit_limit as number) > 0){
      this.isDisabled = false;
    }
    this.creditSettingsForm = this.rootForm.control.get(this.formGroupName) as FormGroup;
    this.creditSettingsForm.get("cc_surcharge_enabled")?.disable();

    this.creditSettingsFormUpdate();
  }

  get creditSettingsFormData() { return this.creditSettingsForm.controls; }

  creditSettingsFormUpdate() {
    setTimeout(() => {this.creditSettingsForm.patchValue({
        default_credit_term_id : this.supplierData.default_credit_term_id,
        default_credit_limit : this.supplierData.default_credit_limit,
        payment_portal_setup_enabled :  this.supplierData.payment_portal_setup_enabled,
        cc_surcharge_enabled: this.supplierData.cc_surcharge_enabled,
        first_order_prepay_reqd: this.supplierData.first_order_prepay_reqd,
        additional_charge_text : this.supplierData.additional_charge_text,
        additional_charge_amt : parseFloat(this.supplierData.additional_charge_amt).toFixed(2),
        first_order_prepay_cc : this.supplierData.first_order_prepay_cc,
        first_order_prepay_ach : this.supplierData.first_order_prepay_ach,
    })}, 2000);
  }

  /**
  * Disable input box default credit limit
  * 
  */
  disableCreditLimit() {
    this.hascreditLimit = 0;
    if (typeof (this.hascreditLimit) != "undefined") {
         if (this.hascreditLimit == 0) {
             this.isDisabled = true;
             this.supplierData.default_credit_limit = -1;
             const updateSupplierDataToEmit = {
              supplierData : -1,
              settingsElementName : "default_credit_limit"
             }
             this.updateSupplierData.emit(updateSupplierDataToEmit)
         } else {
             this.isDisabled = false;
         }
     }
  };

  /**
  * Enable input box default credit limit
  * 
  */
  enableCreditLimit() {
    this.hascreditLimit = 1;
    this.isDisabled = false;
  };

  // Trackby function for track looping items
  trackByFn(index:number, item:any){
    return item
  }

  /**
   * Function to emit the updateSupplier Data to listen that into the parent component
   * @param {string | boolean | number} supplierData
   * @param {string} settingsElementName
   */
  callUpdateSupplierDataFunc(supplierData:string | boolean | number, settingsElementName:string) {
    const valuesToUpdate = [
        "payment_portal_setup_enabled",
        "cc_surcharge_enabled",
        "first_order_prepay_reqd",
        "first_order_prepay_cc",
        "first_order_prepay_ach"
    ];
    Object.keys(this.creditSettingsForm.controls).forEach((controlName) => {
        this.supplierData[controlName] = this.creditSettingsForm.get(controlName)?.value;
    });
    supplierData = this.creditSettingsForm.get(settingsElementName)?.value;
    if(valuesToUpdate.includes(settingsElementName)){
        supplierData = supplierData ? 1 : 0;
    }
    if (settingsElementName === 'additional_charge_amt') {
        supplierData = Number(supplierData);
    }
    this.validateFirstOrderPrepay();
    if (!this.fopValidationFlag) {
        const updateSupplierDataToEmit: UpdateSupplierDataInterface = {
            supplierData : supplierData,
            settingsElementName : settingsElementName
        }
        this.updateSupplierData.emit(updateSupplierDataToEmit);
    }
    if (this.fopValidationFlag) {
        this.updateFopValidation.emit();
    }
    
    // if first_order_prepay_cc or first_order_prepay_ach checked then need to enable first_order_prepay_reqd field also
    if (!this.fopValidationFlag && supplierData === 1 
        && (settingsElementName === 'first_order_prepay_cc' || settingsElementName === 'first_order_prepay_ach')) {
        this.saveFopValue('first_order_prepay_reqd');
        this.saveFopValue('first_order_prepay_cc');
        this.saveFopValue('first_order_prepay_ach');
    }
    /**
      * Sending req to uncheck first_order_prepay_cc and first_order_prepay_ach
      * when first_order_prepay_reqd is unchecked.
    */
    if (settingsElementName === 'first_order_prepay_reqd' && supplierData === 0) {
        this.creditSettingsForm.patchValue({
            first_order_prepay_cc : false,
            first_order_prepay_ach : false
        });
        this.callUpdateSupplierDataFunc(false, 'first_order_prepay_cc');
        this.callUpdateSupplierDataFunc(false, 'first_order_prepay_ach');
    }
  }
  
  /**
   * Method to validate First order prepay required checkbox
   * if First order prepay required checkbox is checked then need to require at least one of the checkboxes
   * first_order_prepay_cc or first_order_prepay_ach
  */
  validateFirstOrderPrepay() {
    var fopCheckValue = this.creditSettingsForm.get('first_order_prepay_reqd')?.value;
    var fopCCValue = this.creditSettingsForm.get('first_order_prepay_cc')?.value;
    var fopAchValue = this.creditSettingsForm.get('first_order_prepay_ach')?.value;
    this.fopValidationFlag = false;
    if (fopCheckValue && !fopCCValue && !fopAchValue) {
        this.fopValidationFlag = true;
    }
  }
  
  /**
   * Method to save First order prepay required checkbox values
  */
  saveFopValue(valueToUpdate: any) {
        const updateSupplierDataToEmit: UpdateSupplierDataInterface = {
            supplierData : this.creditSettingsForm.get(valueToUpdate)?.value ? 1 : 0,
            settingsElementName : valueToUpdate
        }
        this.updateSupplierData.emit(updateSupplierDataToEmit);
  }

  /**
  * Function to emit the saveSupplierPtype Data to listen that into the parent component
  * @param {number} value
  * @param {boolean} check
  */
  callSaveSupplierPtypeFunc(value: number, event: any){
    const saveSupplierPtypeDataToEmit: SaveSupplierEmitterInterface = { 
      value : value,
      isChecked : event.target.checked
    }
    this.saveSupplierPtype.emit(saveSupplierPtypeDataToEmit)
  }

  /**
   * Validates Credit limit
  */    
  creditLimitValidationMsg:string = "Please enter Valid Credit Limit. Allowed upto 99999.99 and Default value is -1";
  validateCreditLimit(creditLimit:string | number, status:boolean, field:string) {
      var fieldErrMsg = "show_"+field+"_err_msg";
      const inputField = this.creditSettingsForm.get(field)
      if (creditLimit != -1 && creditLimit !== null && creditLimit !== '' && creditLimit !== undefined) {
          if(!/(^\d{0,5}$)|(^\d{0,5}(\.\d{1,2})$)/.test(creditLimit.toString()) && status) {
              inputField?.setErrors({creditLimit: true})
          }
      }
  };

  isPaymentTypeChecked(id: number): boolean {
    return this.ptypeSelected.includes(id);
  }

  onAdditionalChargeAmtBlur() {
    this.additionalChargeAmtError = "";
    const value = this.creditSettingsForm.get('additional_charge_amt')?.value??0;
    if (isNaN(value) || Number(value) < 0) {
      this.additionalChargeAmtError = 'Value should be greater than or equal to 0';
      // Do not call updateSupplierDataFunc
      return;
    } else if (Number(value) > 0 && !/(^\d{0,5}$)|(^\d{0,5}(\.\d{1,2})$)/.test(value.toString())) {
        this.additionalChargeAmtError = 'Value is out of range, allowed up to 99999.99';
        return;
    } else {
      this.creditSettingsForm.get('additional_charge_amt')?.setValue(parseFloat(value).toFixed(2));
      this.additionalChargeAmtError = '';
      this.callUpdateSupplierDataFunc(value, 'additional_charge_amt');
    }
  }
}
