<template>
    <div class="fragment">
        <div v-if="basketItemCount" class="basketWrapper">
            <!-- Order Summary Area -->
            <div class="orderSummaryArea" v-if="loaded">
                <div class="orderSummaryBox">
                    <h4>Order Summary</h4>
                    <div class="innerSummary">
                        <basket-items
                            :items="basket.items"
                            :hide-inputs="hideInputs"
                            :placeholder-image="basketPlaceholderImage"
                            :show-sizes="config.itemsSizes"
                            :site="config.site"
                            @remove-item="removeItem"
                            @change-stock="changeStock"
                            @update-stock="updateStock"
                        />
                        <basket-totals
                            :basket="basket"
                            :currencies="currencies"
                            :errors="errors"
                            :messages="messages"
                            :coupon-enabled="config.couponEnabled"
                            :show-vat="config.basketShowVat"
                            :vat-enabled="config.vatEnabled"
                            :vat-rate="config.vatRate"
                            :show-delivery-options="showDeliveryOptions"
                            :current-delivery-name="currentDeliveryName"
                            @update-coupon-code="updateCouponCode"
                            @validate-coupon="validateCoupon"
                            @clear-coupon="clearCoupon"
                            @update-delivery="updateDelivery"
                            @update-field="updateBasketField"
                        />
                    </div>
                </div>

                <div class="checkoutActions">
                    <a class="continueShoppingLink" href="/browse">Continue Shopping</a>
                    <a href="#" id="mobileCheckoutButton" class="button">Begin Secure Checkout</a>
                </div>
            </div>

            <!-- User Details Area -->
            <div class="userDetailsWrap">
                <div id="userDetails" class="formInline">
                    <!-- Blacklisted Error -->
                    <div class="row validationMessage" v-if="hasField('errors.blacklisted')">
                        <span>{{ errors.blacklisted }}</span>
                    </div>

                    <h2 class="checkoutTitle">Checkout Now</h2>

                    <!-- Member Login Section (slot for Twig content) -->
                    <slot name="member-login"></slot>

                    <!-- Personal Details Section -->
                    <div class="checkoutSectionWrap" v-if="loaded">
                        <h4 class="checkoutSectionTitle">Personal Details</h4>
                        <personal-details
                            :basket="basket"
                            :genders="genders"
                            :errors="errors"
                            :member-id="config.memberId"
                            :members-section="config.membersSection"
                            :members-basket="config.membersBasket"
                            :cardholder-password="cardholderPassword"
                            @clear-error="clearError"
                            @update-field="updateBasketField"
                            @update-password="updatePassword"
                        />
                        <id-check
                            v-if="basket.require_id_check"
                            :basket="basket"
                            :id-check-data="idCheckData"
                            :errors="errors"
                            :member-verified="config.memberIsVerified"
                            @clear-error="clearError"
                            @update-id-field="updateIdCheckField"
                            @build-id-number="buildIdCheckNumber"
                            @clear-id-number="clearIdCheckNumber"
                        />
                    </div>

                    <!-- Billing Details Section -->
                    <div class="checkoutSectionWrap" v-if="loaded">
                        <h4 class="checkoutSectionTitle">Billing Details</h4>

                        <div class="row" v-if="basket.require_id_check">
                            <div class="alert complyMessage">
                                <span>Please enter your billing address. This is the one which is linked to your bank account and allows us to complete your ID check. You can add a different delivery address below</span>
                            </div>
                        </div>

                        <address-section
                            type="billing"
                            :basket="basket"
                            :countries="countries"
                            :state-list="stateList"
                            :has-postcodes="hasPostcodes"
                            :errors="errors"
                            :allow-alternate-delivery="config.allowAlternateDelivery"
                            @clear-error="clearError"
                            @update-field="updateBasketField"
                            @shipping-trigger="shippingTrigger"
                            @store-details="storeDetails"
                        />

                        <!-- Alternative Delivery Details -->
                        <div
                            v-if="config.allowAlternateDelivery"
                            class="row"
                            :class="{ alternate_delivery: !basket.billing_address_used }"
                            id="shipAddress"
                        >
                            <h4 class="checkoutSectionTitle">Alternative Delivery Details (Optional)</h4>
                            <address-section
                                type="shipping"
                                :basket="basket"
                                :countries="countries"
                                :state-list="stateList"
                                :has-postcodes="hasPostcodes"
                                :errors="errors"
                                @clear-error="clearError"
                                @update-field="updateBasketField"
                                @shipping-trigger="shippingTrigger"
                                @store-details="storeDetails"
                            />
                        </div>
                    </div>

                    <!-- Order Notes Section -->
                    <order-notes
                        v-if="config.orderNotesEnabled"
                        :message="basket.info.message"
                        :max-length="config.orderNotesMaxLength"
                        :errors="errors"
                        @update-message="updateOrderMessage"
                    />

                    <!-- How Did You Hear Section -->
                    <how-did-you-hear
                        v-if="config.howDidYouHearEnabled && !config.memberId"
                        :basket="basket"
                        :choices="howDidYouHearChoices"
                        @update-field="updateBasketField"
                    />

                    <!-- Newsletter Checkbox -->
                    <div class="row">
                        <input
                            type="checkbox"
                            name="newsletter"
                            id="newsletter"
                            :checked="!!basket.info.newsletter"
                            @change="updateBasketField({ path: 'info.newsletter', value: $event.target.checked ? 1 : 0 })"
                            value="on"
                        />
                        <label for="newsletter">
                            I want to receive updates and special offers via email
                        </label>
                    </div>

                    <!-- Terms and Conditions -->
                    <terms-newsletter
                        v-if="config.termsShow"
                        :terms="terms"
                        :errors="errors"
                        @update-terms="updateTerms"
                        @clear-error="clearError"
                    />

                    <!-- Checkout Button -->
                    <checkout-actions
                        :loaded="loaded"
                        :busy="busy"
                        :basket="basket"
                        @try-checkout="tryCheckout"
                    />

                    <!-- Payment button slots (for Judopay etc) -->
                    <slot name="payment-buttons"></slot>

                    <!-- Error Messages -->
                    <div id="basketStockError" v-if="loaded && basket.stock_error">
                        <div class="alert error">
                            One or more items in your basket has exceeded available stock, please change the quantities of these items.
                        </div>
                    </div>
                    <div id="basketLimitError" v-if="loaded && basket.limit_error && Object.keys(basket.limit_error).length">
                        <div class="alert error">
                            One or more items in your basket has exceeded the purchase limit
                        </div>
                    </div>
                    <div id="basketGeneralError" v-if="loaded && basket.general_error">
                        <div class="alert error">
                            {{ basket.general_error }}
                        </div>
                    </div>
                    <div id="basketIncompatibilityError" v-if="loaded && basket.incompatibility_error">
                        <div class="alert error">
                            The medication in the basket have restrictions. Please see the list of medication for more information.
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Empty Basket State -->
        <div
            class="emptyBasket"
            v-else
            :class="{ loading: busy }"
        >
            <div class="emptyBasketMessage">
                <loading-spinner
                    :loading="busy"
                    :loading-text="emptyBasketMessage"
                    :show-loading-text="true"
                />
                <h4 v-if="!busy">{{ emptyBasketMessage }}</h4>
            </div>
        </div>
    </div>
</template>

<script>
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex';
import BasketItems from './sections/basket_items.vue';
import BasketTotals from './sections/basket_totals.vue';
import PersonalDetails from './sections/personal_details.vue';
import AddressSection from './sections/address_section.vue';
import IdCheck from './sections/id_check.vue';
import OrderNotes from './sections/order_notes.vue';
import HowDidYouHear from './sections/how_did_you_hear.vue';
import TermsNewsletter from './sections/terms_newsletter.vue';
import CheckoutActions from './sections/checkout_actions.vue';

export default {
    name: 'mtc-checkout',

    components: {
        BasketItems,
        BasketTotals,
        PersonalDetails,
        AddressSection,
        IdCheck,
        OrderNotes,
        HowDidYouHear,
        TermsNewsletter,
        CheckoutActions
    },

    provide() {
        return {
            formatPrice: this.multiCurrency
        };
    },

    props: {
        // Allow config to be passed as props for flexibility
        initialConfig: {
            type: Object,
            default: () => ({})
        }
    },

    computed: {
        ...mapState('checkout', [
            'basket',
            'busy',
            'loaded',
            'terms',
            'currencies',
            'countries',
            'genders',
            'titles',
            'errors',
            'messages',
            'config',
            'id_check_data',
            'empty_basket_message',
            'basket_placeholder_image',
            'how_did_you_hear_about_us_choices',
            'state_list',
            'has_postcodes',
            'cardholder_password'
        ]),

        ...mapGetters('checkout', [
            'basketItemCount',
            'hasDoctorItems',
            'showDeliveryOptions',
            'currentDeliveryName',
            'otherForHowDidYouHear',
            'hasStates',
            'canEditQty'
        ]),

        // Aliases for cleaner template access
        hideInputs() {
            return this.$store.state.checkout.hide_inputs;
        },
        idCheckData() {
            return this.id_check_data;
        },
        emptyBasketMessage() {
            return this.empty_basket_message;
        },
        basketPlaceholderImage() {
            return this.basket_placeholder_image;
        },
        howDidYouHearChoices() {
            return this.how_did_you_hear_about_us_choices;
        },
        stateList() {
            return this.state_list;
        },
        hasPostcodes() {
            return this.has_postcodes;
        },
        cardholderPassword() {
            return this.cardholder_password;
        }
    },

    created() {
        // Merge any props config
        if (this.initialConfig && Object.keys(this.initialConfig).length) {
            this.SET_CONFIG(this.initialConfig);
        }

        // Initialize - fetches all data via AJAX
        this.initFromBootstrap();
    },

    mounted() {
        // Disable enter key on form
        this.$el.closest('form')?.addEventListener('keypress', (e) => {
            if (e.which === 13) {
                e.preventDefault();
                return false;
            }
        });
    },

    methods: {
        ...mapActions('checkout', [
            'initFromBootstrap',
            'fetchBasket',
            'applyBasketPayload',
            'callUpdate',
            'removeItem',
            'validateCoupon',
            'shippingTrigger',
            'clearIdCheckNumber',
            'buildIdCheckNumber'
        ]),

        ...mapMutations('checkout', [
            'SET_CONFIG',
            'SET_BASKET_FIELD',
            'SET_TERMS',
            'CLEAR_ERROR',
            'SET_ID_CHECK_FIELD_VALUE',
            'SET_CARDHOLDER_PASSWORD'
        ]),

        /**
         * Check if a nested field exists and has a truthy value
         */
        hasField(field) {
            if (typeof field !== 'string' || !field.length) return false;
            try {
                return field.split('.').reduce((obj, key) => (obj ? obj[key] : undefined), this);
            } catch (err) {
                return false;
            }
        },

        /**
         * Clear a validation error
         */
        clearError(path) {
            this.CLEAR_ERROR(path);
        },

        /**
         * Update a basket field
         */
        updateBasketField({ path, value }) {
            this.SET_BASKET_FIELD({ path, value });
        },

        /**
         * Update order notes message
         */
        updateOrderMessage(message) {
            this.SET_BASKET_FIELD({ path: 'info.message', value: message });
        },

        /**
         * Update terms checkbox
         */
        updateTerms(value) {
            this.SET_TERMS(value);
        },

        /**
         * Update cardholder password
         */
        updatePassword(value) {
            this.SET_CARDHOLDER_PASSWORD(value);
        },

        /**
         * Update ID check field value
         */
        updateIdCheckField({ type, index, value }) {
            this.SET_ID_CHECK_FIELD_VALUE({ type, index, value });
        },

        /**
         * Handle item quantity change
         */
        changeStock(item) {
            // Update the item quantity in the store immediately so the input stays responsive
            const itemIndex = this.basket.items.findIndex(i => i.id === item.id);
            if (itemIndex !== -1) {
                const newItems = [...this.basket.items];
                newItems[itemIndex] = { ...newItems[itemIndex], quantity: item.quantity };
                this.SET_BASKET_FIELD({ path: 'items', value: newItems });
            }
            // Debounce the server round-trip so a multi-digit entry fires one update, not one per keystroke.
            if (item.quantity > 0) {
                clearTimeout(this._quantityUpdateTimer);
                this._quantityUpdateTimer = setTimeout(() => {
                    this.callUpdate({ action: 'update_qty', focusOn: 'item_' + item.id });
                }, 400);
            }
        },

        /**
         * Handle item stock update (on blur)
         */
        updateStock(item) {
            if (item.quantity < 1) {
                this.removeItem(item);
            }
        },

        /**
         * Handle delivery option change
         */
        updateDelivery(deliveryId) {
            this.SET_BASKET_FIELD({ path: 'delivery_selected', value: deliveryId });
            this.callUpdate({ action: 'store_details' });
        },

        /**
         * Persist field changes (e.g. address country/state) to the server.
         */
        storeDetails() {
            this.callUpdate({ action: 'store_details' });
        },

        /**
         * Update coupon code in store
         */
        updateCouponCode(code) {
            this.SET_BASKET_FIELD({ path: 'coupon_code', value: code });
        },

        /**
         * Clear applied coupon
         */
        clearCoupon() {
            this.callUpdate({ action: 'clear_coupon' });
        },

        /**
         * Try to proceed to checkout
         */
        async tryCheckout() {
            const result = await this.callUpdate({ action: 'try_checkout' });

            if (!result.success && result.errors) {
                // Scroll to first error
                this.$nextTick(() => {
                    const firstError = this.$el.querySelector('.errorWrap');
                    if (firstError) {
                        // Check for fixed header and get its height
                        const header = document.querySelector('.headerContainer');
                        let headerOffset = 20;
                        if (header) {
                            const headerStyle = window.getComputedStyle(header);
                            if (headerStyle.position === 'fixed' || headerStyle.position === 'sticky') {
                                headerOffset = header.offsetHeight + 20;
                            }
                        }
                        const offsetTop = firstError.getBoundingClientRect().top + window.scrollY - headerOffset;
                        window.scrollTo({
                            top: offsetTop,
                            behavior: 'smooth'
                        });
                    }
                });
            }
        },

        /**
         * Multi-currency formatting helper
         */
        multiCurrency(value) {
            // Use the filter from the parent Vue instance if available
            if (this.$options.filters && this.$options.filters.multi_currency) {
                return this.$options.filters.multi_currency(value);
            }
            // Fallback formatting
            const currency = this.currencies?.GBP || { symbol: '\u00A3', ratio: 1 };
            const amount = parseFloat(value) * (currency.ratio || 1);
            return currency.symbol + amount.toFixed(2);
        }
    }
};
</script>
