/* global Shopware */

import '../../component/vrpayment-order-action-completion';
import '../../component/vrpayment-order-action-refund';
import '../../component/vrpayment-order-action-refund-partial';
import '../../component/vrpayment-order-action-refund-by-amount';
import '../../component/vrpayment-order-action-void';
import template from './index.html.twig';
import './index.scss';

const {Component, Mixin, Filter, Context, Utils} = Shopware;
const Criteria = Shopware.Data.Criteria;

Component.register('vrpayment-order-detail', {
	template,

	inject: [
		'VRPaymentTransactionService',
		'VRPaymentRefundService',
		'repositoryFactory'
	],

	mixins: [
		Mixin.getByName('notification')
	],

	data() {
		return {
			transactionData: {
				transactions: [],
				refunds: []
			},
			transaction: {},
			lineItems: [],
			refundableQuantity: 0,
			itemRefundableQuantity: 0,
			isLoading: true,
			orderId: '',
			currency: '',
			modalType: '',
			refundAmount: 0.00,
			refundableAmount: 0.00,
			itemRefundedAmount: 0.00,
			itemRefundedQuantity: 0,
			itemRefundableAmount: 0.00,
			currentLineItem: '',
			refundLineItemQuantity: [],
			refundLineItemAmount: [],
			selectedItems: []
		};
	},

	metaInfo() {
		return {
			title: this.$tc('vrpayment-order.header')
		};
	},


	computed: {
		dateFilter() {
			return Filter.getByName('date');
		},

		relatedResourceColumns() {
			return [
				{
					property: 'paymentMethodName',
					label: this.$tc('vrpayment-order.transactionHistory.types.payment_method'),
					rawData: true
				},
				{
					property: 'state',
					label: this.$tc('vrpayment-order.transactionHistory.types.state'),
					rawData: true
				},
				{
					property: 'currency',
					label: this.$tc('vrpayment-order.transactionHistory.types.currency'),
					rawData: true
				},
				{
					property: 'authorized_amount',
					label: this.$tc('vrpayment-order.transactionHistory.types.authorized_amount'),
					rawData: true
				},
				{
					property: 'id',
					label: this.$tc('vrpayment-order.transactionHistory.types.transaction'),
					rawData: true
				},
				{
					property: 'customerId',
					label: this.$tc('vrpayment-order.transactionHistory.types.customer'),
					rawData: true
				}
			];
		},

		lineItemColumns() {
			return [
			    // It must be set in order to have correctly working checkbox mechanism
				{
					property: 'id',
					rawData: true,
					visible: false,
					primary: true
				},
				{
					property: 'uniqueId',
					label: this.$tc('vrpayment-order.lineItem.types.uniqueId'),
					rawData: true,
					visible: false,
					primary: true
				},
				{
					property: 'name',
					label: this.$tc('vrpayment-order.lineItem.types.name'),
					rawData: true
				},
				{
					property: 'quantity',
					label: this.$tc('vrpayment-order.lineItem.types.quantity'),
					rawData: true
				},
				{
					property: 'amountIncludingTax',
					label: this.$tc('vrpayment-order.lineItem.types.amountIncludingTax'),
					rawData: true
				},
				{
					property: 'type',
					label: this.$tc('vrpayment-order.lineItem.types.type'),
					rawData: true
				},
				{
					property: 'taxAmount',
					label: this.$tc('vrpayment-order.lineItem.types.taxAmount'),
					rawData: true
				},
				{
					property: 'refundableQuantity',
					rawData: true,
					visible: false,
				},
			];
		},

		refundColumns() {
			return [
				{
					property: 'id',
					label: this.$tc('vrpayment-order.refund.types.id'),
					rawData: true,
					visible: true,
					primary: true
				},
				{
					property: 'amount',
					label: this.$tc('vrpayment-order.refund.types.amount'),
					rawData: true
				},
				{
					property: 'state',
					label: this.$tc('vrpayment-order.refund.types.state'),
					rawData: true
				},
				{
					property: 'createdOn',
					label: this.$tc('vrpayment-order.refund.types.createdOn'),
					rawData: true
				}
			];
		}
	},

	watch: {
		'$route'() {
			this.resetDataAttributes();
			this.createdComponent();
		}
	},

	created() {
		this.createdComponent();
	},

	methods: {
		createdComponent() {
			this.orderId = this.$route.params.id;
			const orderRepository = this.repositoryFactory.create('order');
			const orderCriteria = new Criteria(1, 1);
			orderCriteria.addAssociation('transactions');
			orderCriteria.getAssociation('transactions').addSorting(Criteria.sort('createdAt', 'DESC'));

			orderRepository.get(this.orderId, Context.api, orderCriteria).then((order) => {
				this.order = order;
				this.isLoading = false;
				var totalAmountTemp = 0;
				var refundsAmountTemp = 0;
				const vrpaymentTransactionId = order.transactions[0].customFields.vrpayment_transaction_id;
				this.VRPaymentTransactionService.getTransactionData(order.salesChannelId, vrpaymentTransactionId)
					.then((VRPaymentTransaction) => {
						this.currency = VRPaymentTransaction.transactions[0].currency;

						VRPaymentTransaction.transactions[0].authorized_amount = Utils.format.currency(
							VRPaymentTransaction.transactions[0].authorizationAmount,
							this.currency
						);

						VRPaymentTransaction.refunds.forEach((refund) => {
							refundsAmountTemp = parseFloat(parseFloat(refundsAmountTemp) + parseFloat(refund.amount));
							refund.amount = Utils.format.currency(
								refund.amount,
								this.currency
							);

							refund.reductions.forEach((reduction) => {
							    if (reduction.quantityReduction > 0) {
                                    if (this.refundLineItemQuantity[reduction.lineItemUniqueId] === undefined) {
                                        this.refundLineItemQuantity[reduction.lineItemUniqueId] = reduction.quantityReduction;
                                    } else {
                                        this.refundLineItemQuantity[reduction.lineItemUniqueId] += reduction.quantityReduction;
                                    }
							    }
                                if (reduction.unitPriceReduction > 0) {
                                    if (this.refundLineItemAmount[reduction.lineItemUniqueId] === undefined) {
                                        this.refundLineItemAmount[reduction.lineItemUniqueId] = reduction.unitPriceReduction;
                                    } else {
                                        this.refundLineItemAmount[reduction.lineItemUniqueId] += reduction.unitPriceReduction;
                                    }
                                }
							});

						});

						VRPaymentTransaction.transactions[0].lineItems.forEach((lineItem) => {
							if (!lineItem.id) {
								lineItem.id = lineItem.uniqueId;
                            }

                            lineItem.itemRefundedAmount = parseFloat(this.refundLineItemAmount[lineItem.uniqueId] || 0) * parseInt(lineItem.quantity);
                            lineItem.amountIncludingTax = parseFloat(lineItem.amountIncludingTax) || 0;

                            lineItem.itemRefundedQuantity = parseInt(this.refundLineItemQuantity[lineItem.uniqueId]) || 0;
                            lineItem.refundableAmount = parseFloat(
                              (lineItem.amountIncludingTax - lineItem.itemRefundedAmount).toFixed(2)
                            );

							lineItem.amountIncludingTax = Utils.format.currency(
								lineItem.amountIncludingTax,
								this.currency
							);

							lineItem.taxAmount = Utils.format.currency(
								lineItem.taxAmount,
								this.currency
							);

							totalAmountTemp = parseFloat(parseFloat(totalAmountTemp) + parseFloat(lineItem.unitPriceIncludingTax * lineItem.quantity));

							lineItem.refundableQuantity = parseInt(
								parseInt(lineItem.quantity) - parseInt(this.refundLineItemQuantity[lineItem.uniqueId] || 0)
							);

						});

						this.lineItems = VRPaymentTransaction.transactions[0].lineItems;
						this.transactionData = VRPaymentTransaction;
						this.transaction = this.transactionData.transactions[0];
						this.refundAmount = Number(this.transactionData.transactions[0].amountIncludingTax);
						this.refundableAmount = parseFloat(parseFloat(totalAmountTemp) - parseFloat(refundsAmountTemp));

					}).catch((errorResponse) => {
					try {
						this.createNotificationError({
							title: this.$tc('vrpayment-order.paymentDetails.error.title'),
							message: errorResponse.message,
							autoClose: false
						});
					} catch (e) {
						this.createNotificationError({
							title: this.$tc('vrpayment-order.paymentDetails.error.title'),
							message: errorResponse.message,
							autoClose: false
						});
					} finally {
						this.isLoading = false;
					}
				});
			});
		},
		downloadPackingSlip() {
			window.open(
				this.VRPaymentTransactionService.getPackingSlip(
					this.transaction.metaData.salesChannelId,
					this.transaction.id
				),
				'_blank'
			);
		},

		downloadInvoice() {
			window.open(
				this.VRPaymentTransactionService.getInvoiceDocument(
					this.transaction.metaData.salesChannelId,
					this.transaction.id
				),
				'_blank'
			);
		},

		resetDataAttributes() {
			this.transactionData = {
				transactions: [],
				refunds: []
			};
			this.lineItems = [];
			this.refundLineItemQuantity = [];
			this.refundLineItemAmount = [];
			this.isLoading = true;
		},

		spawnModal(modalType, lineItemId, refundableQuantity, itemRefundableAmount) {
			this.modalType = modalType;
			this.currentLineItem = lineItemId;
			this.itemRefundableQuantity = refundableQuantity;
            this.itemRefundableAmount = !isNaN(itemRefundableAmount) ? Math.round(itemRefundableAmount * 100) / 100 : 0;
		},

		closeModal() {
			this.modalType = '';
		},

		lineItemRefund(lineItemId) {
			this.isLoading = true;
			this.VRPaymentRefundService.createRefund(
				this.transactionData.transactions[0].metaData.salesChannelId,
				this.transactionData.transactions[0].id,
				0,
				lineItemId
			).then(() => {
				this.createNotificationSuccess({
					title: this.$tc('vrpayment-order.refundAction.successTitle'),
					message: this.$tc('vrpayment-order.refundAction.successMessage')
				});
                this.isLoading = false;
                this.$emit('modal-close');
                this.$nextTick(() => {
                    this.$router.replace(`${this.$route.path}?hash=${Utils.createId()}`);
                });
			}).catch((errorResponse) => {
				try {
					this.createNotificationError({
						title: errorResponse.response.data.errors[0].title,
						message: errorResponse.response.data.errors[0].detail,
						autoClose: false
					});
				} catch (e) {
					this.createNotificationError({
						title: errorResponse.title,
						message: errorResponse.response.data,
						autoClose: false
					});
				} finally {
                    this.isLoading = false;
                    this.$emit('modal-close');
                    this.$nextTick(() => {
                        this.$router.replace(`${this.$route.path}?hash=${Utils.createId()}`);
                    });
				}
			});
		},
		isSelectable(item) {
			return item.refundableQuantity > 0 && item.refundableAmount > 0 && item.itemRefundedAmount == 0 && item.itemRefundedQuantity == 0;
		},
		onSelectionChanged(selection) {
			this.selectedItems = Object.values(selection);
		},
        onPerformBulkAction() {
            if (this.selectedItems.length) {
                // Set isLoading to true to show the loader
                this.isLoading = true;

                // Force the DOM to update before proceeding with the asynchronous operations
                this.$nextTick(() => {
                    const refundPromises = this.selectedItems.map((item) => {
                        return this.lineItemRefundBulk(item.uniqueId); // Simulated refund action with delay
                    });

                    // Wait for all refund promises to complete
                    Promise.all(refundPromises)
                        .then(() => {
                            // Once all promises are resolved, hide the loader and close the modal
                            this.isLoading = false;
                            this.$emit('modal-close');
                            this.$nextTick(() => {
                                this.$router.replace(`${this.$route.path}?hash=${Utils.createId()}`);
                            });
                        })
                        .catch((error) => {
                            // Handle any errors during the refund process
                            this.createNotificationError({
                                title: 'Error',
                                message: 'Something went wrong with the refunds',
                                autoClose: false
                            });
                            this.isLoading = false; // Ensure the loader is hidden even on error
                        });
                });
            }
        },
        lineItemRefundBulk(lineItemId) {
            return new Promise((resolve, reject) => {
                this.VRPaymentRefundService.createRefund(
                    this.transactionData.transactions[0].metaData.salesChannelId,
                    this.transactionData.transactions[0].id,
                    0,
                    lineItemId
                )
                .then(() => {
                    this.createNotificationSuccess({
                        title: this.$tc('vrpayment-order.refundAction.successTitle'),
                        message: this.$tc('vrpayment-order.refundAction.successMessage')
                    });
                    resolve();
                })
                .catch((errorResponse) => {
                    try {
                        this.createNotificationError({
                            title: errorResponse.response.data.errors[0].title,
                            message: errorResponse.response.data.errors[0].detail,
                            autoClose: false
                        });
                    } catch (e) {
                        this.createNotificationError({
                            title: errorResponse.title,
                            message: errorResponse.response.data,
                            autoClose: false
                        });
                    } finally {
                        reject();
                    }
                });
            });
        },
	}
});
