define([
    "jquery",
    "uiComponent",
    "ko",
    "mage/translate",
    'Magento_Checkout/js/model/quote',
    'Magento_Ui/js/modal/modal',
    'mage/validation',
    'Magento_Checkout/js/action/set-shipping-information',
    'Magento_Checkout/js/action/select-shipping-method',
    'Magento_Checkout/js/model/checkout-data-resolver',
    'Magento_Checkout/js/checkout-data',
    'Magento_Checkout/js/model/shipping-rate-processor/customer-address',
    'Magento_Checkout/js/model/shipping-rate-processor/new-address',
    'Magento_Checkout/js/model/shipping-rate-registry',
    'Magento_Checkout/js/model/shipping-service',
    'Magento_Customer/js/customer-data'

], function ($,
             Component,
             ko,
             __,
             quote,
             modal,
             validation,
             setShippingInformationAction,
             selectShippingMethodAction,
             checkoutDataResolver,
             checkoutData,
             shippingRateProcessCustomerAddress,
             shippingRateProcessNewAddress,
             rateRegistry,
             shippingService,
             storage
) {
    'use strict';

    return Component.extend({
        cacheKey: 'orlen-data',
        defaults: {
            template: 'Macopedia_OrlenShipping/map'
        },

        userAddress: ko.observable(),
        pointId: ko.observable(),
        $modal: null,
        config: {},

        initialize: function (options) {
            this._super();

            this._config = options;
            let obj = this.getData();

            if (obj.selectedPoint &&
                obj.pointDescription &&
                obj.destinationCode &&
                obj.quoteId == quote.getQuoteId()) {

                this.pointId(obj.selectedPoint);

                $.post(this._config.saveUrl, {
                    description: obj.pointDescription,
                    destination_code: obj.destinationCode,
                });
            } else if (obj.selectedPoint) {
                this.saveData({ selectedPoint: null });
            }

            quote.shippingAddress.subscribe(this.onShippingAddressChange.bind(this));

            return this;
        },

        onShippingAddressChange: function (newAddress) {
            if (Array.isArray(newAddress.street) && 'postcode' in newAddress && 'city' in newAddress) {
                const address = `${newAddress.street.join(' ')} ${newAddress.postcode} ${newAddress.city}`;
                if (address.trim().length > 0) {
                    this.userAddress(address);
                }
            }
        },

        getData: function () {
            let data = storage.get(this.cacheKey)();

            if ($.isEmptyObject(data)) {
                data = $.initNamespaceStorage('mage-cache-storage')
                    .localStorage.get(this.cacheKey) || { selectedPoint: null };

                this.saveData(data);
            }

            return data;
        },

        openModal: function () {
            if (!window?.OrlenPaczkaWidget) {
                this.initOrlenWidgetScript();
            }
            this.$modal.modal('openModal');
        },

        saveData: function (data) {
            storage.set(this.cacheKey, data);
        },

        setPoint: function (_component, event) {
            const self = this;
            const pointData = event.detail?.marker?.options;
            this.pointId(pointData.id)
            const description = `${pointData?.groupName ?? ''}, \n${pointData?.addressLine ?? ''}, ${pointData?.city ?? ''} ${pointData?.postalCode ?? ''}`;

            $.post(self._config.saveUrl, {
                description: description,
                destination_code: pointData.destinationCode,
            }).done(function (data) {
                if (data.type === "success") {
                    let obj = self.getData();
                    obj.selectedPoint = self.pointId();
                    obj.pointDescription = description;
                    obj.destinationCode = pointData.destinationCode;
                    obj.quoteId = quote.getQuoteId();
                    self.saveData(obj);

                    const shippingMethod = {
                        carrier_code: self._config.carrierCode,
                        method_code: self._config.carrierCode
                    };

                    checkoutDataResolver.resolveShippingRates([shippingMethod]);

                    if (quote.shippingAddress().customerAddressId) {
                        rateRegistry.set(quote.shippingAddress().getKey(), false);
                        shippingRateProcessCustomerAddress.getRates(quote.shippingAddress());
                    } else {
                        rateRegistry.set(quote.shippingAddress().getCacheKey(), false);
                        shippingRateProcessNewAddress.getRates(quote.shippingAddress());
                    }

                    self.selectShippingMethod(shippingMethod);
                }
            });

            this.$modal.modal('closeModal');
        },

        /**
         * @param {Object} shippingMethod
         * @return {Boolean}
         */
        selectShippingMethod: function(shippingMethod) {
            selectShippingMethodAction(shippingMethod);
            checkoutData.setSelectedShippingRate(shippingMethod['carrier_code'] + '_' + shippingMethod['method_code']);

            return true;
        },

        /**
         * Initialize Orlen widget script
         */
        initOrlenWidgetScript: function () {
            if (document.getElementById('orlen-widget-script') || 'OrlenPaczkaWidget' in window) {
                return
            }
            const script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = `https://mapa.orlenpaczka.pl/widget.js?token=${this._config.token}&v=1.0.0&t=${Math.floor(new
            Date().getTime() / 1000)}`;
            script.id = 'orlen-widget-script';
            document.head.appendChild(script);
        },

        /**
         * Prepare modal and register event listener
         * @returns {*}
         */
        renderOrlenWidget: function () {
            const self = this;

            this.$modal = $(this._config.modalSelector).modal({
                type: 'popup',
                title: $.mage.__('Choose pick-up point'),
                responsive: true,
                innerScroll: false,
                buttons: []
            });

            /**
             * Global event listener for Orlen pickup point button
             */
            $('body').on('click', '.orlen-shipping-button', () => this.openModal());

            return this;
        }
    });
});
