<template>

    <div class="upsellsPopup__row" :class="{ 'is-added': added }">

        <div class="upsellsPopup__thumb">
            <img
                    v-if="upsell.image"
                    :src="upsell.image"
                    :alt="upsell.name"
                    loading="lazy"
            />
        </div> <!-- .upsellsPopup__thumb -->

        <div class="upsellsPopup__rowBody">

            <div class="upsellsPopup__rowText">
                <h3 class="upsellsPopup__rowName" v-text="upsell.name"></h3>
                <p
                        class="upsellsPopup__rowMeta"
                        v-if="metaLabel"
                        v-text="metaLabel"
                ></p>
            </div> <!-- .upsellsPopup__rowText -->

            <!-- Multi-size upsells get the same pill selector as the product page;
                 single/zero-size products add their only variant directly. -->
            <product-size-select
                    v-if="hasSizeSelector"
                    :sizes="upsell.sizes"
                    :single-select="false"
                    :selected-size-id="selectedSizeId"
                    @change="onSizeChange"
            ></product-size-select>

            <div class="upsellsPopup__rowFooter">

                <div class="upsellsPopup__price">
                    <span
                            class="upsellsPopup__priceNow"
                            :class="{ 'upsellsPopup__priceNow--sale': onSale }"
                            v-text="formatPrice(currentPrice)"
                    ></span>
                    <span
                            class="upsellsPopup__priceWas"
                            v-if="onSale"
                            v-text="formatPrice(basePrice)"
                    ></span>
                </div> <!-- .upsellsPopup__price -->

                <button
                        type="button"
                        class="upsellsPopup__add"
                        :disabled="added || loading"
                        @click="add"
                >
                    <span v-if="added">Added</span>
                    <span v-else>+ Add</span>
                </button>

            </div> <!-- .upsellsPopup__rowFooter -->

            <p class="upsellsPopup__rowError" v-if="error" role="alert">
                Sorry, this could not be added. Please try again.
            </p>

        </div> <!-- .upsellsPopup__rowBody -->

    </div> <!-- .upsellsPopup__row -->

</template>

<script>

import axios from 'axios';
import productSizeSelect from '@components/shop/item/partials/product_size_select.vue';

export default {
    name: 'UpsellsRow',
    components: {
        productSizeSelect,
    },
    props: {
        upsell: {
            type: Object,
            default() {
                return {};
            }
        },
    },
    data() {
        return {
            selectedSizeId: 0,
            added: false,
            loading: false,
            error: false,
        };
    },
    computed: {

        sizes() {
            return Array.isArray(this.upsell.sizes) ? this.upsell.sizes : [];
        },

        hasSizeSelector() {
            return this.sizes.length > 1;
        },

        // The size whose price drives the row. Falls back to the only size, then null.
        selectedSize() {
            if (!this.sizes.length) {
                return null;
            }
            return this.sizes.find(size => size.id === this.selectedSizeId) || this.sizes[0];
        },

        basePrice() {
            return this.selectedSize ? Number(this.selectedSize.price) : Number(this.upsell.price);
        },

        baseSalePrice() {
            return this.selectedSize ? Number(this.selectedSize.sale_price) : Number(this.upsell.sale_price);
        },

        onSale() {
            return this.baseSalePrice > 0 && this.baseSalePrice < this.basePrice;
        },

        currentPrice() {
            return this.onSale ? this.baseSalePrice : this.basePrice;
        },

        // The size selector communicates the variant when present, so only show
        // the static meta line otherwise.
        metaLabel() {
            return this.hasSizeSelector ? '' : this.upsell.meta;
        },
    },
    created() {
        if (this.sizes.length) {
            this.selectedSizeId = this.sizes[0].id;
        }
    },
    methods: {

        onSizeChange(id) {
            this.selectedSizeId = Number(id);
        },

        formatPrice(value) {
            return '£' + Number(value).toFixed(2);
        },

        // Upsells are non-assessment products, so addtobasket adds inline and
        // returns JSON with no redirect. Stay open; flip the button to "Added".
        add() {

            if (this.added || this.loading) {
                return;
            }

            this.loading = true;
            this.error = false;

            const params = new URLSearchParams();
            params.set('ajax', 'true');
            params.set('id', this.upsell.id);
            params.set('quantity', '1');
            params.set('add-bag', 'true');

            if (this.sizes.length) {
                params.set('size', this.selectedSize.id);
            }

            axios.post('/shop/addtobasket.php', params, {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            })
            .then((response) => {
                if (response.data && response.data.status === 'ok') {
                    this.added = true;
                    if (window.EventBus) {
                        window.EventBus.$emit('receiveBasketUpdate');
                    }
                    this.$emit('added', this.upsell.id);
                } else {
                    this.error = true;
                }
            })
            .catch(() => {
                this.error = true;
            })
            .finally(() => {
                this.loading = false;
            });
        },
    },
}
</script>
