const defaultCustomItem = {
    name: '',
    customItem: true,
    size_price: '',
    strength: '',
    qty: '',
};

Vue.component('basketBuilderForm', {

    props: [
        'memberData',
        'parentId',
        'isInline',
        'events',
    ],

    data: function() {
        return {
            deliveryMethods: [],
            siteUrl: '',
            members: [],
            member: {},
            items: [],
            foundItems: [],
            memberQuery: '',
            itemQuery: '',
            errors: [],
            success: false,
            successText: '',
            itemsTotal: 0,
            deliveryMethodId: 0,
            orderId: 0,
            customItemMode: false,
            customItem: {},
            showMemberSearch: true,
            showBuilder: false,
            eventIndex: 0,
            _memberSearchTimer: null,
            _itemsSearchTimer: null,
            // NEW: controls whether we’re building or showing success
            // 'build'  -> show item picker and normal builder UI
            // 'success'-> show success panel only (no picker)
            stage: 'build',
        };
    },

    mounted: function() {
        this.init();
    },

    watch: {
        items: {
            deep: true,
            handler() {
                this.calculateTotals();
            }
        },
        memberData(member) {
            if (typeof member.id !== 'undefined') {
                this.selectMember(member);
                this.showMemberSearch = false;
            }
        },
        events(stack) {
            // Because there may be more than one event at a time, loop through new events
            for (let i = this.eventIndex; i < stack.length; i++) {
                let event = stack[i];
                if (event.name === 'initBasketBuilder') {
                    // Fresh open: clear transient state but KEEP the selected member
                    this.errors = [];
                    this.success = false;
                    this.successText = '';
                    this.orderId = 0;
                    this.items = [];
                    this.foundItems = [];
                    this.itemsTotal = 0;
                    this.deliveryMethodId = 0;
                    this.customItemMode = false;
                    this.customItem = Object.assign({}, defaultCustomItem);
                    // We’re entering a new build flow
                    this.stage = 'build';
                    // If a member is already selected, skip the member search panel
                    this.showMemberSearch = !(this.member && this.member.id);
                    // Show builder content before the overlay clones the DOM
                    this.showBuilder = true;
                    this.$nextTick(function () {
                        try { $(window).trigger('resize.overlay'); } catch (e) {}
                    });
                }
                if (event.name === 'hideBasketBuilder') {
                    this.showBuilder = false;
                }
            }
            // Update event index so that we don't process already processed events
            this.eventIndex = stack.length;
        }
    },

    methods: {
        // --- NEW: tolerant JSON parser that accepts string/obj and strips junk ---
        parseResponse(raw) {
            if (raw == null) return {};
            if (typeof raw === 'object') return raw;
            if (typeof raw !== 'string') return {};

            const trimmed = raw.trim();
            try {
                return JSON.parse(trimmed);
            } catch (e) {
                // Try to pull out the first balanced {...} block if notices/HTML wrapped it
                const start = trimmed.indexOf('{');
                const end   = trimmed.lastIndexOf('}');
                if (start !== -1 && end !== -1 && end > start) {
                    try {
                        return JSON.parse(trimmed.slice(start, end + 1));
                    } catch (_) {}
                }
                console.error('Invalid JSON from BasketBuilder endpoint:', trimmed);
                return { success: false, errors: { general: 'Invalid server response' } };
            }
        },
        // ------------------------------------------------------------------------

        init() {
            if (this.isInline) {
                this.showBuilder = true;
            }
            if (typeof this.memberData.id !== 'undefined') {
                this.selectMember(this.memberData);
                this.showMemberSearch = false;
            }
            let vm = this;
            this.$http.post('/plugins/BasketBuilder/admin/ajax.php', {
                action: 'init',
            }).then(function (response) {
                const data = vm.parseResponse(response.data);
                if (data.success) {
                    vm.deliveryMethods = data.deliveryMethods;
                    vm.siteUrl = data.siteUrl;
                    return;
                }
                vm.errors = data.errors || { general: 'Failed to initialize' };
            });
        },

        debouncedSearchMembers() {
            clearTimeout(this._memberSearchTimer);
            this._memberSearchTimer = setTimeout(() => {
                if ((this.memberQuery || '').length < 3) return;
                this.searchMembers();
            }, 500);
        },

        searchMembers() {
            let vm = this;
            vm.success = false;
            vm.successText = '';
            vm.orderId = 0;
            this.$http.post('/plugins/BasketBuilder/admin/ajax.php', {
                action: 'searchMembers',
                query: this.memberQuery,
            }).then(function (response) {
                const data = vm.parseResponse(response.data);
                if (data.success) {
                    vm.members = data.members;
                    return;
                }
                vm.errors = data.errors || { general: 'Search failed' };
            });
        },

        debouncedsearchItems() {
            // Do nothing if we’re not in build stage
            if (this.stage !== 'build') return;
            clearTimeout(this._itemsSearchTimer);
            this._itemsSearchTimer = setTimeout(() => {
                if ((this.itemQuery || '').length < 3) return;
                this.searchItems();
            }, 500);
        },

        searchItems() {
            // Do nothing if we’re not in build stage
            if (this.stage !== 'build') return;
            let vm = this;
            vm.success = '';
            this.$http.post('/plugins/BasketBuilder/admin/ajax.php', {
                action: 'searchItems',
                query: this.itemQuery,
            }).then(function (response) {
                const data = vm.parseResponse(response.data);
                if (data.success) {
                    vm.foundItems = data.items;
                    vm.$nextTick(function () {
                        $(window).trigger('resize.overlay');
                    });
                    return;
                }
                vm.errors = data.errors || { general: 'Search failed' };
            });
        },

        showCustomItem() {
            // Copy defaults
            this.customItem = Object.assign({}, defaultCustomItem);
            this.customItemMode = true;
        },

        addCustomItem() {
            let item = Object.assign({}, this.customItem);
            item.size = item.qty + 'x' + item.strength;
            this.selectItem(item);
            this.customItemMode = false;
        },

        amendQuantity(index, event) {
            this.items[index].quantity = parseInt(event.target.value);
            this.calculateTotals();
        },

        calculateTotals() {
            this.itemsTotal = 0;
            for (let i = 0; i < this.items.length; i++) {
                let price = this.items[i].size ?
                    this.items[i].size_price :
                    this.items[i].price;
                // Play with numbers a bit so that we don't get crazy decimals
                price = Math.round(price * 100);
                this.$set(this.items[i], 'total', price * this.items[i].quantity / 100);
                this.itemsTotal += price * this.items[i].quantity;
            }
            this.itemsTotal /= 100;
        },

        prefillShipping(member) {
            const bill = member.address_billing || {};
            const ship = member.address_shipping || {};

            // pick ship → bill → fallback ''
            const pick = (s, b) => (s !== undefined && s !== null && s !== '') ? s
                : (b !== undefined && b !== null ? b : '');

            // ensure the object exists and is reactive
            if (!member.address_shipping) {
                this.$set(member, 'address_shipping', {});
            }

            this.$set(member.address_shipping, 'firstname', pick(ship.firstname, bill.firstname));
            this.$set(member.address_shipping, 'lastname',  pick(ship.lastname,  bill.lastname));
            this.$set(member.address_shipping, 'address1',  pick(ship.address1,  bill.address1));
            this.$set(member.address_shipping, 'address2',  pick(ship.address2,  bill.address2));
            this.$set(member.address_shipping, 'city',      pick(ship.city,      bill.city));
            this.$set(member.address_shipping, 'postcode',  pick(ship.postcode,  bill.postcode));
        },

        selectMember(member) {
            if (member.address_shipping === null) {
                member.address_shipping = {};
            }
            this.prefillShipping(member);
            this.member = member;
            this.members = [];
            this.memberQuery = '';
        },

        selectItem(item) {
            item.quantity = 1;
            let items = this.items;
            items.push(item);
            this.$set(this, 'items', items);
            this.calculateTotals();
            this.clearItemSearch();
            $('#itemQuery').focus();
        },

        removeItem(index) {
            this.items.splice(index, 1);
            this.calculateTotals();
        },

        clearItemSearch() {
            this.itemQuery = '';
            this.foundItems = [];
        },

        submitBasket() {
            let vm = this;
            this.$http.post('/plugins/BasketBuilder/admin/ajax.php', {
                action: 'createBasket',
                items: this.items,
                memberId: this.member.id,
                deliveryMethodId: this.deliveryMethodId,
                shippingAddress: this.member.address_shipping,
                parentId: this.parentId,
            }).then(function (response) {
                const data = vm.parseResponse(response.data);
                if (data.success) {
                    vm.items = [];
                    vm.foundItems = [];
                    // Keep the selected member so the next open starts at item picker
                    vm.members = [];
                    // After success, do not show the picker until the next initBasketBuilder
                    vm.success = true;
                    vm.stage = 'success';
                    vm.showMemberSearch = false;
                    vm.orderId = data.order.id;
                    vm.successText = 'Basket and order created successfully!';
                    vm.emitEvent('orderCreated');
                    vm.$nextTick(function () {
                        try { $(window).trigger('resize.overlay'); } catch (e) {}
                    });
                    return;
                }
                vm.errors = data.errors || { general: 'Create basket failed' };
            });
        },

        sendToMember() {
            let vm = this;
            this.$http.post('/plugins/BasketBuilder/admin/ajax.php', {
                action: 'sendToMember',
                orderId: this.orderId,
            }).then(function (response) {
                const data = vm.parseResponse(response.data);
                if (data.success) {
                    vm.successText = 'Payment link sent successfully!';
                    return;
                }
                vm.errors = data.errors || { general: 'Send link failed' };
            });
        },

        copyURL() {
            navigator.clipboard.writeText(this.siteUrl + '/shop/checkout/basket_overview.php?order_id=' + this.orderId);
        },
        emitEvent(name, data) {
            this.$parent.emitEvent(name, data)
        },
    },
});
