import { Component, Input, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
import { Subscription } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';

import { CartService } from 'src/app/services/cart/cart.service';
import { OrdersService } from 'src/app/services/orders/orders.service';
import { SessionService } from 'src/app/services/session/session.service';
import { AccountInfoService } from 'src/app/services/accountInfo/account-info.service';
import { SessionDataInterface } from 'src/app/interfaces/session-data-interface';
import { NgbModal, NgbModalConfig, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { ModalConfig } from 'src/app/interfaces/common-interfaces';
import { environment } from 'src/environments/environment';
import { Router } from '@angular/router';
import { PaymentStatusMessageModalComponent } from '../payment-status-message-modal/payment-status-message-modal.component';
import { StripePaymentModelComponent } from 'src/app/components/stripe-payment-model/stripe-payment-model.component';

@Component({
  standalone: false,
  selector: 'app-resubmit-payment-modal',
  templateUrl: './resubmit-payment-modal.component.html',
  styleUrls: ['./resubmit-payment-modal.component.scss']
})
export class ResubmitPaymentModalComponent implements OnInit {
    @Input() order!:any;
    @Input() resubmitModalClose!: () => void;
    @Input() payType!:string;
    imgUrl: string = environment.imageUrl;
    isCollapsable!:boolean;
    payMethodAdded: boolean = false;
    paymentMethodsSubscribe!:Subscription;
    surchargeAmtSubscribe!:Subscription;
    displayChangeMethod: boolean  = true;
    disableResubmit:boolean = false;
    disablePayNow:boolean = false;
    resubmitPaymentMethod!:string;
    resubmitPaymentId!:string;
    resubmitSurchargeAmt!: number;
    prepaySuppliers: { [id: number]: 'both' | 'ccOnly' | 'achOnly' } = {};
    refreshMethodsSubscribe!: Subscription;
    session!: SessionDataInterface['data'];
    customerSupport!:string;
    isPayNow: boolean = false;
    constructor(
        private cartService: CartService,
        private router: Router,
        private orders: OrdersService,
        private modalService: NgbModal,
        private accountInfoService: AccountInfoService,
        private sessionService : SessionService,
        private cdr: ChangeDetectorRef
    ) { }
    ngOnInit(): void {
        this.session = this.sessionService.getSession();
        this.customerSupport = this.session.trxade_number;
        this.resubmitSurchargeAmt = this.order.surcharge_amount;
        this.resubmitPaymentMethod = this.order.payment_method;
        this.resubmitPaymentId = this.order.stripe_payment_method_id;
        if (this.order.payment_type_cc && !this.order.payment_type_ach) {
            this.prepaySuppliers[this.order.seller_id] = 'ccOnly';
        } else if (!this.order.payment_type_cc && this.order.payment_type_ach) {
            this.prepaySuppliers[this.order.seller_id] = 'achOnly';
        } else if (this.order.payment_type_cc && this.order.payment_type_ach) {
            this.prepaySuppliers[this.order.seller_id] = 'both';
        }
        if (this.payType === 'paynow') {
            this.isPayNow = true;
        }
    }
    
    /**
     * Method to Calculate Order total
     * excludes item for calculation  which has the status Item Cancelled(21) or Unaccepted(3)
     * @param {type} items
     * @returns {Number}
    */
    setOrderTotal (items: any) {
      var total = 0;
      var excludeStatusArr = [3, 21];
      items.forEach( (item: any) => {
        if (excludeStatusArr.indexOf(item.flag_status) === -1) {
          total += item.bid_amount * item.quantity_offered;
        }
      })
      return total;
    };

     /**
     * Resubmits payment for an order
     * @param orderId 
     * @param paymentMethodId
     * @param payType
     */
    submitPayment(orderId: number, paymentMethodId: any, payType: any) {
        this.disablePayNow = true;
        this.orders.submitPayment(orderId, paymentMethodId, payType).subscribe({
            next: (res: any) => {
                this.resubmitModalClose();
                if (res.data.success) {
                    if (res.data.order_info.payment_type !=='card') {
                        this.order.stripe_payment_type = res.data.order_info.payment_type; 
                        this.order.resubmit_payment = 1;
                    }
                } else if (payType == 'resubmit') {
                    this.order.resubmit_pmt_reset_by_admin = res.data.order_info.resubmit_pmt_reset_by_admin;
                    this.order.resubmit_attempt = res.data.order_info.resubmit_attempt;
                }
                if (res.data) {
                    this.order.payment_method = this.resubmitPaymentMethod;
                    this.order.ship_fee = res.data.order_info.ship_fee;
                    this.order.additional_charge_amt = res.data.order_info.additional_charge_amt;
                    this.order.surcharge_amount = res.data.order_info.surcharge_amount;
                    this.order.stripe_payment_date_ts = res.data.order_info.order_processed_time;
                    this.order.payment_status = res.data.order_info.stripe_pay_status;
                }
                this.cdr.detectChanges();
                this.displayPaymentMsgModal(res.data);
            },
            error: (err) => {
              this.orders.errorCallBack(err);
            },
            complete: () => { },
        });
    }

    /*
    * Private Property for base modal config for paymentMsgModalConfig
    */
    paymentMsgModalConfig:ModalConfig = {
     showHeader: false,
     title: ""
    };

    /**
    * Display payment status message Modal popup
    * @returns void
    */
    paymentMsgModalSub!:NgbModalRef;
    displayPaymentMsgModal(resopnseData: any) {
      this.paymentMsgModalConfig.title = "";
      this.paymentMsgModalSub = this.modalService.open(PaymentStatusMessageModalComponent, {size: 'sm'});
      this.paymentMsgModalSub.componentInstance.responseData = resopnseData;
      this.paymentMsgModalSub.componentInstance.paymentMsgModalClose = () => {
        this.paymentMsgModalClose();
      };
    };

    /*
     * Method to close payment status message modal
    */
    paymentMsgModalClose() {
       this.paymentMsgModalSub.close('ok');
    };

    /**
     * To update payment-related values when switching to a new payment method
     * @param {any} event
     * @param {number} suppId
     * @return void
    */
    changePaymentMethod(event: any, suppId: any) {
        var paymentId = event.target.value;
        var selectedOption = event.target.selectedOptions[0];
        var paymentMethod = selectedOption.text;
        if (paymentMethod == 'Add New') {
            this.showStripePaymentModel();
        } else {
            this.displayPaymentDropDown(true);
            this.getOrderSurchargeAmt(paymentId);
            this.resubmitPaymentMethod = paymentMethod;
            this.resubmitPaymentId = paymentId;
        }
    }
    
    /**
     * refresh change method dropdown values after add new paymentmethod in stripe payment modal popup
     * get stripe payment methods
    */
    refreshPaymentMethods() {
        this.refreshMethodsSubscribe = this.accountInfoService.getStripePayMethods()
        .subscribe({
            next: (res: any) => {
                if (res?.data && res.data.length > 0) {
                    this.getOrderSurchargeAmt(res.data[0].id);
                    this.order.payment_methods = res.data;
                    this.resubmitPaymentMethod = res.data[0].name;
                    this.resubmitPaymentId = res.data[0].id;
                }
            },
            error: (err) => {
              this.cartService.errorCallBack(err);
            },
            complete: () => { },
        }); 
    }
    
    /**
     * Gets Order Payment method surcharge amount
    */
    getOrderSurchargeAmt(paymentMethodId: any) {
        this.disableResubmit = false;
        this.surchargeAmtSubscribe = this.orders.getPaymentMethodSurcharge(this.order.order_id, paymentMethodId)
        .subscribe({
            next: (res: any) => {
                if (!res.data.error_msg) {
                    this.resubmitSurchargeAmt = res.data.surcharge_amount;
                } else {
                    this.disableResubmit = true;
                }
            },
            error: (err) => {
              this.disableResubmit = true;
              this.orders.errorCallBack(err);
            },
            complete: () => { },
        }); 
    }

    /**
     * Method to set the flag to display/hide the "Change method" text/payment methods dropdown
     * @param {boolean} displayFlag
     * @return void
    */
    displayPaymentDropDown(displayFlag: boolean) {
       this.displayChangeMethod = displayFlag;
    }

    /**
     * Opens the Stripe payment modal for setting up a payment method.
     * Subscribes to the addPayMethodStatus event to update the payment method status.
     */
    stripePaymentModel!: NgbModalRef
    showStripePaymentModel() {
        this.paymentMethodsSubscribe = this.accountInfoService
        .getAllPaymentMethods()
        .subscribe({
            next: (res: any) => {
                if (res.data !== false) {
                    this.payMethodAdded = true;
                    this.stripePaymentModel = this.modalService.open(StripePaymentModelComponent,{size: 'sm'});
                    this.stripePaymentModel.componentInstance.stripePaymentModel = this.stripePaymentModel;
                    this.stripePaymentModel.componentInstance.stripePaymentModelNo = this.stripePaymentModelNo;
                    this.stripePaymentModel.componentInstance.paymentMethodCards = res.data?.cards || [];
                    this.stripePaymentModel.componentInstance.paymentMethodBank = res.data?.bankAccounts || [];
                    this.stripePaymentModel.componentInstance.pendingBankPymentMethods = res.data?.pendingBankPayMethods || [];
                    this.stripePaymentModel.componentInstance.isFromCart = false;
                     // Subscribe to addPayMethodStatus event
                    this.stripePaymentModel.componentInstance.addPayMethodStatus.subscribe((data: any) => {
                        if (data.status) {
                            this.refreshPaymentMethods();
                        }
                    });
                    this.stripePaymentModel.componentInstance.deletePaymentMethod.subscribe(() => {
                        this.refreshPaymentMethods();
                    });
                }
            },
            error: (err: HttpErrorResponse) => {
              this.accountInfoService.errorCallBack(err);
            },
            complete: () => { }
        });
    };
    
    /**
     * Dismisses the Stripe payment modal.
     * @param action
     */
    stripePaymentModelNo(action: any) {
        this.stripePaymentModel.dismiss();
    };

    ngOnDestroy(): void {
        this.paymentMethodsSubscribe?.unsubscribe();
        this.refreshMethodsSubscribe?.unsubscribe();
        this.surchargeAmtSubscribe?.unsubscribe();
    }
}
