<template>
    <div
        class="quick-order-row"
        :class="{
            'quick-order-row--out-of-stock': isOutOfStock,
            'quick-order-row--assessment': requiresAssessment,
            'quick-order-row--just-added': justAdded
        }"
    >
        <div class="quick-order-row__image">
            <a :href="product.url">
                <img :src="product.image" :alt="product.name" loading="lazy" />
            </a>
        </div>

        <div class="quick-order-row__info">
            <a :href="product.url" class="quick-order-row__name">{{ product.name }}</a>
            <span v-if="isPharmacyType" class="quick-order-row__badge">{{ badgeLabel }}</span>
        </div>

        <div class="quick-order-row__price">
            <span v-if="originalPrice" class="quick-order-row__price--original"><span v-html="currencySymbol"></span>{{ originalPrice }}</span>
            <span class="quick-order-row__price--current">
                <span v-if="showFromLabel" class="quick-order-row__price-label">from</span>
                <span v-html="currencySymbol"></span>{{ displayPrice }}
            </span>
        </div>

        <div class="quick-order-row__size" v-if="hasSizes">
            <product-size-select
                :sizes="visibleSizes"
                :single-select="true"
                @change="onSizeChange"
            ></product-size-select>
        </div>

        <div class="quick-order-row__quantity" v-if="!isOutOfStock && !requiresAssessment">
            <mtc-number-input
                ref="qtyInput"
                :value="quantity"
                :min="1"
                :max="99"
                @input="onQuantityChange"
                @keydown.native.enter.prevent="addToBasket"
            ></mtc-number-input>
        </div>

        <div class="quick-order-row__action">
            <button
                v-if="!isOutOfStock"
                type="button"
                class="button quick-order-row__btn"
                :class="{ 'is-loading': adding, 'is-added': justAdded }"
                :disabled="!canAdd && !requiresAssessment"
                @click="addToBasket"
            >
                <span v-if="justAdded">Added{{ addedCount > 1 ? ' (' + addedCount + ')' : '' }} &mdash; Add more</span>
                <span v-else>{{ actionLabel }}</span>
            </button>
            <span v-else class="quick-order-row__out-of-stock">Out of Stock</span>

            <div
                v-if="message"
                class="quick-order-row__message"
                :class="'quick-order-row__message--' + messageType"
                role="status"
            >
                {{ message }}
            </div>
        </div>
    </div>
</template>

<script>
import axios from 'axios';
import { EventBus, vueEventHub } from '@site/js/event-bus.js';
import productSizeSelect from '@components/shop/item/partials/product_size_select.vue';
import mtcNumberInput from '@components/mtc_number_input.vue';

export default {
    name: 'QuickOrderRow',
    components: {
        productSizeSelect,
        mtcNumberInput
    },
    props: {
        product: {
            type: Object,
            required: true
        }
    },
    data() {
        return {
            selectedSizeId: null,
            quantity: 1,
            adding: false,
            message: '',
            messageType: '',
            messageTimer: null,
            justAdded: false,
            justAddedTimer: null,
            addedCount: 0,
            activeCurrency: window.active_currency || 'GBP'
        };
    },
    mounted() {
        this.onCurrencyChange = () => {
            this.activeCurrency = window.active_currency;
        };
        vueEventHub.$on('currency-change', this.onCurrencyChange);
    },
    computed: {
        currencyRecord() {
            const currencies = window.active_currencies || [];
            const list = Array.isArray(currencies) ? currencies : Object.values(currencies);
            return list.find(c => c.currency === this.activeCurrency) || null;
        },
        currencySymbol() {
            return this.currencyRecord ? this.currencyRecord.symbol : '&pound;';
        },
        currencyRatio() {
            if (!this.currencyRecord) return 1;
            const ratio = parseFloat(this.currencyRecord.ratio);
            return isNaN(ratio) ? 1 : ratio;
        },
        visibleSizes() {
            if (!this.product.sizes || this.product.sizes.length === 0) return [];
            return this.product.sizes.filter(s => s.stock > 0);
        },
        hasSizes() {
            return this.visibleSizes.length > 0;
        },
        hasMultipleSizePrices() {
            if (this.visibleSizes.length < 2) return false;
            const effective = this.visibleSizes.map(this.effectivePrice);
            return Math.min(...effective) !== Math.max(...effective);
        },
        selectedSize() {
            if (!this.selectedSizeId || !this.hasSizes) return null;
            return this.visibleSizes.find(s => s.id === this.selectedSizeId);
        },
        itemLevelPrice() {
            const price = parseFloat(this.product.price);
            return isNaN(price) ? parseFloat(this.product.from_price) || 0 : price;
        },
        itemLevelSalePrice() {
            const sale = parseFloat(this.product.sale_price);
            return isNaN(sale) ? 0 : sale;
        },
        itemLevelEffectivePrice() {
            const sale = this.itemLevelSalePrice;
            const price = this.itemLevelPrice;
            return (sale > 0 && sale < price) ? sale : price;
        },
        fromPriceNumber() {
            if (this.visibleSizes.length > 0) {
                return Math.min(...this.visibleSizes.map(this.effectivePrice));
            }
            return this.itemLevelEffectivePrice;
        },
        displayPrice() {
            const base = this.selectedSize
                ? this.effectivePrice(this.selectedSize)
                : this.fromPriceNumber;
            return (base * this.currencyRatio).toFixed(2);
        },
        originalPrice() {
            if (this.selectedSize) {
                const sale = parseFloat(this.selectedSize.sale_price);
                const price = parseFloat(this.selectedSize.price);
                if (sale > 0 && sale < price) {
                    return (price * this.currencyRatio).toFixed(2);
                }
                return null;
            }
            if (!this.hasSizes) {
                const sale = this.itemLevelSalePrice;
                const price = this.itemLevelPrice;
                if (sale > 0 && sale < price) {
                    return (price * this.currencyRatio).toFixed(2);
                }
            }
            return null;
        },
        showFromLabel() {
            return !this.selectedSize && this.hasMultipleSizePrices;
        },
        requiresAssessment() {
            return this.product.requires_assessment;
        },
        isOutOfStock() {
            if (!this.product.in_stock) return true;
            if (this.product.sizes && this.product.sizes.length > 0 && this.visibleSizes.length === 0) return true;
            return false;
        },
        isPharmacyType() {
            return ['pharmacy', 'doctor'].includes(this.product.product_type);
        },
        badgeLabel() {
            if (this.product.product_type === 'doctor') return 'Prescription';
            if (this.product.product_type === 'pharmacy') return 'Pharmacy';
            return '';
        },
        canAdd() {
            return !this.isOutOfStock && !this.requiresAssessment && (!this.hasSizes || this.selectedSizeId !== null);
        },
        actionLabel() {
            if (this.requiresAssessment) return 'Complete consultation';
            return 'Add to basket';
        }
    },
    methods: {
        focus() {
            if (this.requiresAssessment || this.isOutOfStock) return;
            this.$nextTick(() => {
                const input = this.$refs.qtyInput && this.$refs.qtyInput.$el
                    ? this.$refs.qtyInput.$el.querySelector('input')
                    : null;
                if (input) {
                    input.focus();
                    input.select && input.select();
                }
            });
        },
        effectivePrice(size) {
            const sale = parseFloat(size.sale_price);
            const price = parseFloat(size.price);
            return (sale > 0 && sale < price) ? sale : price;
        },
        onSizeChange(sizeId) {
            this.selectedSizeId = sizeId;
            this.clearMessage();
        },
        onQuantityChange(value) {
            this.quantity = Number(value);
        },
        clearMessage() {
            this.message = '';
            this.messageType = '';
            if (this.messageTimer) {
                clearTimeout(this.messageTimer);
                this.messageTimer = null;
            }
        },
        showMessage(text, isSuccess) {
            this.message = text;
            this.messageType = isSuccess ? 'success' : 'error';
            this.messageTimer = setTimeout(() => {
                this.clearMessage();
            }, 4000);
        },
        flashAdded(qty) {
            this.addedCount += qty;
            this.justAdded = true;
            if (this.justAddedTimer) clearTimeout(this.justAddedTimer);
            this.justAddedTimer = setTimeout(() => {
                this.justAdded = false;
                this.addedCount = 0;
            }, 3500);
        },
        addToBasket() {
            if (this.requiresAssessment) {
                this.$emit('show-assessment-modal', {
                    assessmentUrl: this.product.assessment_url,
                    productName: this.product.name
                });
                return;
            }

            if (!this.canAdd) {
                if (this.hasSizes && !this.selectedSizeId) {
                    this.showMessage('Please select a size', false);
                }
                return;
            }

            this.adding = true;
            const qty = this.quantity;

            const formData = new FormData();
            formData.append('id', this.product.id);
            formData.append('quantity', qty);
            formData.append('ajax', 'true');

            if (this.selectedSizeId) {
                formData.append('size', this.selectedSizeId);
            }

            axios.post('/shop/addtobasket.php', formData)
                .then(response => {
                    const data = response.data;
                    if (data.status === 'ok') {
                        EventBus.$emit('receiveBasketUpdate');
                        this.flashAdded(qty);
                        this.clearMessage();
                    } else if (data.error === 'size') {
                        this.showMessage('Please select a size', false);
                    } else if (data.error === 'assessment_required') {
                        this.$emit('show-assessment-modal', {
                            assessmentUrl: data.url,
                            productName: this.product.name
                        });
                    } else {
                        this.showMessage(data.message || 'Unable to add to basket', false);
                    }
                })
                .catch(() => {
                    this.showMessage('Unable to add to basket', false);
                })
                .finally(() => {
                    this.adding = false;
                });
        }
    },
    beforeDestroy() {
        vueEventHub.$off('currency-change', this.onCurrencyChange);
        if (this.messageTimer) clearTimeout(this.messageTimer);
        if (this.justAddedTimer) clearTimeout(this.justAddedTimer);
    }
};
</script>
