

Vue.directive('select', {
    twoWay: true,
    deep: true,
    bind: function (el, binding, vNode) {

        $(el).chosen({
            disable_search: true,
            width: '100%'
        })
            .change(function () {

                $(this).val(binding.value);

                if(binding.arg == 'billing' || binding.arg == 'shipping') {
                    // handle.vm.setPafAddress(action);
                }else if (binding.arg == 'id_check_type') {
                    el.vm.clearIdCheckNumber(binding.value);
                }else {
                    el.vm.callUpdate(binding.arg);
                }


            });

    },
    //update: function(el) {
    //return $(el).trigger('chosen:updated');
    //}
});

/*
 * Main checkout basket component
 * Provides all basket functionality including communicating with mini basket
 */
Vue.component('basket', {
    created: function () {

        this.basket = this.input_basket;
        this.hide_inputs = this.input_hide_inputs;
        this.currencies = this.input_currencies;
        this.countries = this.input_countries;

        if(!this.basket?.info?.newsletter) {
            this.basket.info = {
                newsletter: 0
            };
        }

        this.basket.info.newsletter = parseInt(this.basket.info.newsletter);

        let vm = this;

        this.$http.get('/shop/checkout/ajax.php?action=get_basket&ajax').then(function (response) {
            if (response.data.status === 'ok') {
                vm.currencies = response.data.currencies;
                vm.countries = response.data.countries;
                vm.empty_basket_message = 'You have no items in your basket';
                vm.state_list = response.data.state_list;
                vm.has_postcodes = response.data.has_postcodes;
                vm.how_did_you_hear_about_us_choices = response.data.how_did_you_hear_about_us_choices;
                vm.basket = response.data.basket;
                vm.titles = response.data.titles;
                vm.genders = response.data.genders;


                if(!vm.basket.info?.newsletter) {
                    if (typeof vm.basket.info !== 'object') {
                        vm.basket.info = {
                            newsletter: 0
                        };
                    } else {
                        vm.basket.info.newsletter = 0;
                    }
                }
                vm.basket.info.newsletter = parseInt(vm.basket.info.newsletter);

                //Set default gender
                if(vm.default_gender.length) {
                    vm.basket.address.billing.gender = vm.default_gender;
                }


                //Scroll to id check error
                if(typeof vm.basket.require_id_check_cascade != 'undefined') {

                    if(vm.basket.require_id_check_cascade) {
                        setTimeout(function () {

                            if ($('#iderror').length) {

                                var errorOffset = $('#iderror').offset();

                                if (typeof errorOffset.top != 'undefined') {

                                    var off_top = errorOffset.top;
                                    // Scroll to error message
                                    $('html, body').delay(200).animate({
                                        scrollTop: off_top
                                    }, 800);
                                }

                            }

                        }, 500);
                    }

                }

            } else {
                vm.errors.ajax_load = true;
            }
            vm.busy = false;
            vm.loaded = true;
        });
        this.hide_inputs = parseInt(this.hide_inputs, 10);

    },


    props: {
        default_gender: {
            type: [String, Boolean],
            default: () => {
                return '';
            }
        },
        input_basket: {
            type: [Array, Object, String],
            default: () => {
                return [];
            }
        },
        input_hide_inputs: {
            type: [Boolean,Number, String],
            default: 0
        },
        input_currencies: {
            type: [Array, Object, String],
            default: () => {
                return [];
            }
        },
        input_countries: {
            type: [Array, Object, String],
            default: () => {
                return [];
            }
        }
    },
    data: function () {
        return {

            hide_subtotals: true,
            basket: {},
            hide_inputs: 0,
            currencies: {},
            countries: {},

            terms: 0,
            busy: true,
            loaded: false,
            errors: {},
            address: {},
            messages: [],
            newsletter: 0,
            state_list: [],
            has_postcodes: [],
            address_list: {
                billing: [],
                shipping: []
            },
            paf_address: {
                billing: [],
                shipping: []
            },
            code_sent: {
                email: false,
                phone: false
            },
            already_verified: {
                email: false,
                phone: false
            },
            account_verifier: {
                code: {
                    email: [],
                    phone: []
                },
                verified: {
                    email: false,
                    phone: false
                }
            },
            //basket_item_count: 0,
            //show_delivery_options: 1,
            shipping_address_list: [],
            how_did_you_hear_about_us_choices: [],
            last_paf_trigger: '',
            cardholder_password_check: 0,
            show_total_in_pounds: 0,
            cardholder_password: '',
            //current_delivery_name: '',
            empty_basket_message: 'Loading your basket',
            cant_find_address: {
                billing: false,
                shipping: false
            },
            id_check_data: {

                /*
                * ID Check settings
                */
                idOptions: [
                    { id: 'passport', label: 'Passport' },
                    { id: 'id_card', label: 'ID Card' },
                    { id: 'drivers_license', label: 'Drivers License' }
                ],

                //If true, this will add spaces between fields when compiling the final id_number field.
                addSpaces: false,

                //Used for triggering validation errors
                showErrors: false,

                /*
                * ID Check fields
                */

                /*

                    Example input field object for 'passport', 'drivers_license' and 'id_card' arrays:
                    {
                        value: '',
                        placeholder: 'Example',
                        length: 11, // The length of the field - used in maxlength="value" and regex validation
                        regex: '[a-z0-9<]', // Characters for validation - ^, $ and {length} are added later
                        hidden: true // Optional - This will set the input to type="hidden"
                        addChevrons: true // Optional - If true, this will populate a field with
                                          // chevrons to match the length. i.e 1234 will become 1234<<<<<<<
                                          // if the total length is 11 (Can be seen on the passport fields)
                    }

                 */

                passport: [
                    {
                        value: '',
                        placeholder: '107185703',
                        length: 9,
                        regex: '[a-z0-9]'
                    },
                    {
                        value: '',
                        placeholder: '2',
                        length: 1,
                        regex: '[a-z0-9]'
                    },
                    {
                        value: '',
                        placeholder: 'GBR',
                        length: 3,
                        regex: '[a-z]'
                    },
                    {
                        value: '',
                        placeholder: '8501178',
                        length: 7,
                        regex: '[a-z0-9]'
                    },
                    {
                        value: '',
                        placeholder: 'F',
                        length: 1,
                        regex: '[a-z]'
                    },
                    {
                        value: '',
                        placeholder: '1601312',
                        length: 7,
                        regex: '[a-z0-9]'
                    },
                    {
                        value: '<<<<<<<<<<<<<<',
                        placeholder: 'B85475BB<<<<<<',
                        length: 14,
                        regex: '[a-z0-9<]',
                        addChevrons: true,
                        //hidden: true
                    },
                    {
                        value: '',
                        placeholder: '02',
                        length: 2,
                        regex: '[0-9]'
                    }

                ],

                drivers_license: [
                    {
                        value: '',
                        placeholder: 'MORGA',
                        length: 5,
                        regex: '[a-z0-9]'
                    },
                    {
                        value: '',
                        placeholder: '753116',
                        length: 6,
                        regex: '[a-z0-9]'
                    },
                    {
                        value: '',
                        placeholder: 'SM9IJ',
                        length: 5,
                        regex: '[a-z0-9]'
                    }
                ],

                id_card: [
                    {
                        value: '',
                        placeholder: 'ID',
                        length: 2,
                        regex: '[a-z0-9]'
                    },
                    {
                        value: '',
                        placeholder: 'GBR',
                        length: 3,
                        regex: '[a-z]'
                    },
                    {
                        value: '',
                        placeholder: '1234567897',
                        length: 10,
                        regex: '[a-z0-9]'
                    },
                    {
                        value: '<<<<<<<<<<<<<<<',
                        placeholder: '<<<<<<<<<<<<<<<',
                        length: 15,
                        regex: '[a-z0-9<]',
                        hidden: true
                    },
                    {
                        value: '',
                        placeholder: '7704145',
                        length: 7,
                        regex: '[a-z0-9]'
                    },
                    {
                        value: '',
                        placeholder: 'F',
                        length: 1,
                        regex: '[a-z]'
                    },
                    {
                        value: '',
                        placeholder: '1604117',
                        length: 7,
                        regex: '[a-z0-9]'
                    },
                    {
                        value: '',
                        placeholder: 'GBR',
                        length: 3,
                        regex: '[a-z]'
                    },
                    {
                        value: '<<<<<<<<<<<',
                        placeholder: '<<<<<<<<<<<',
                        length: 11,
                        regex: '[a-z0-9]',
                        hidden: true
                    },
                    {
                        value: '',
                        placeholder: '4',
                        length: 1,
                        regex: '[a-z0-9]'
                    },
                ]

            },
        };
    },

    events: {
        'updateBasket': function (basket) {
            this.basket = basket;
        }
    },

    computed: {

        hasDoctorItems: function() {

            if (this.hasField('basket.items')) {

                if(this.hasField('basket.items').length) {

                    const doctorItems = this.basket.items.filter(item => item.product_type == 'doctor');

                    return doctorItems.length > 0;

                }

            }

            return false;

        },

        basket_item_count: function () {
            if (this.hasField('basket.items')) {
                return this.hasField('basket.items').length;
            }
        },
        show_delivery_options: function () {
            var delivery_option_count = 0;
            if (typeof this.basket.delivery_options === 'object') {
                delivery_option_count = this.basket.delivery_options.length;
            }
            return !(this.hide_inputs
                || delivery_option_count < 2
                || this.basket.coupon_freedelivery
            );

        },
        other_for_how_did_you_hear_about_us: function () {
            return this.basket.info.how_did_you_hear_about_us === 'other'
                || (this.basket.info.how_did_you_hear_about_us !== ''
                    && this.how_did_you_hear_about_us_choices.indexOf(this.basket.info.how_did_you_hear_about_us) == -1);
        },
        current_delivery_name: function () {

            if (!this.basket.has_physical_items) {
                return '';
            }

            if (this.basket.coupon_freedelivery) {
                return 'Delivery';
            }

            if (this.basket.delivery_options.length > 1) {
                for (var i = 0; i < this.basket.delivery_options.length; i++) {
                    if (this.basket.delivery_options[i].id === this.basket.delivery_selected) {
                        return this.basket.delivery_options[i].name;
                    }
                }
            } else if (Object.keys(this.basket.delivery_options).length === 1) {
                return this.basket.delivery_options[Object.keys(this.basket.delivery_options)[0]].name;
            }

            return 'No delivery available. Please contact us for delivery options';
        }
    },

    methods: {

        nextDateField: function(e) {

            if(this.$refs.dobDay?.id == e.target.id) {

                if(this.$refs.dobDay?.value?.length === 2) {
                    this.$refs.dobMonth.focus();
                }

            }else if(this.$refs.dobMonth?.id == e.target.id) {

                if(this.$refs.dobMonth?.value?.length === 2) {
                    this.$refs.dobYear.focus();
                }

            }

        },

        multi_currency: function(value) {

            return this.$options.filters.multi_currency(value);

        },

        //Called by changing the id type select
        clearIdCheckNumber: function(type) {

            this.basket.info.id_number = '';

            if(typeof type != 'undefined') {
                this.buildIdCheckNumber(type);
            }

            this.id_check_data.showErrors = false;
        },

        //Automatically add chevrons to fields (For fields with "addChevrons: true")
        addIdCheckChevrons: function(value, length){

            if(value.length && length) {

                var currentLen = value.length;

                while(currentLen < length) {
                    value += '<';
                    currentLen = value.length;
                }

            }

            return value;

        },

        //Jump to the next field once the length has been reached
        nextFieldIdCheck: function(e, type, index) {

            this.buildIdCheckNumber(type);

            var vm = this,
                field = this.id_check_data[type][index];

            //Trigger focus on next field once the length has been met
            if(field.value.length >= field.length) {

                var $ele = $(e.target),
                    $wrapper = $ele.parent().parent(),
                    nextIndex = index + 1,
                    next = false;

                //Find next visible field / field that doesn't start with a chevron
                $wrapper.find('> .row').each(function(i, val){

                    var firstChar = vm.id_check_data[type][i].value[0];

                    if(i > index && !next && $(this).is(':visible') && firstChar != '<') {
                        next = i;
                    }

                });

                //Check if next field exists
                if(next) {

                    var $next = $wrapper.find('.row').eq(next).find('input');

                    if($next.length) {
                        $next.focus();
                    }

                }

            }

        },

        //Build the main id check number based on individual id check tpe fields
        buildIdCheckNumber: function(type) {

            this.basket.info.id_number = '';

            if(this.id_check_data.hasOwnProperty(type)) {

                var fields = this.id_check_data[type],
                    idNumber = '';

                for(var i = 0; i < fields.length; i++) {

                    var field = fields[i];

                    if(field.value.length) {

                        if(this.id_check_data.addSpaces) {
                            idNumber += $.trim(field.value) + ' ';
                        }else{
                            idNumber += $.trim(field.value);
                        }

                    }
                }

                if(idNumber.length) {
                    this.basket.info.id_number = $.trim(idNumber).toUpperCase();
                }

            }

            return false;

        },

        //Validate individual id check fields
        validateIdCheckField: function(e, type, index) {

            var vm = this,
                isValid = false;

            if(this.id_check_data.hasOwnProperty(type)) {

                var field = this.id_check_data[type][index];

                //Populate the rest of the field with chevrons
                if(field.hasOwnProperty('addChevrons')) {
                    if(field.addChevrons) {
                        this.id_check_data[type][index].value = this.addIdCheckChevrons(field.value, field.length);
                    }
                }

                var value = $.trim(field.value),
                    length = field.length,
                    regex = '^' + field.regex + '{' + length + '}$',
                    $ele = $(e.target);

                //Build the full id number
                this.buildIdCheckNumber(type);

                //Check validation
                if(typeof value != 'undefined') {

                    if(value != '') {

                        var regX = new RegExp(regex, 'i'),
                            match = value.match(regX);

                        isValid = match;
                    }

                }

                //Add / Remove error classes
                if(isValid) {
                    $ele.parent().removeClass('errorWrap');
                }else{
                    $ele.parent().addClass('errorWrap');
                }

                //Check all fields for full loss of focus and errors
                setTimeout(function() {

                    var $wrapper = $ele.parent().parent(),
                        focused = $wrapper.find('.row > input:focus').length,
                        errors = $wrapper.find('.row.errorWrap').length;

                    vm.id_check_data.showErrors = (errors > 0);

                },100);

            }

        },



        // Whether user can edit a specific items stock
        canEditQty: function (item) {
            if (typeof item.quantity_lock === 'undefined') {
                return !this.hide_inputs;
            } else {
                return !(this.hide_inputs || item.quantity_lock);
            }
        },

        pafSearchEnabled: function(type) {
            //return true;
            return this.basket.address[type].country === 'GB';
        },

        sendVerificationCode: function(type) {
            var vm = this;
            vm.last_verification_type = type;
            vm.busy = true;
            var target = type === 'email' ? this.basket.info.email : this.basket.info.phone_prefix + this.basket.info.contact_no;
            vm.code_sent[type] = false;
            vm.already_verified[type] = false;

            this.$http.post('/plugins/AccountVerifier/ajax.php', {
                action: 'send_code',
                type: type,
                target: target
            }).then(function (response) {
                vm.busy = false;
                if (response.data.status === 'verified') {
                    vm.messages = response.data.messages;
                    vm.already_verified[vm.last_verification_type] = true;
                } else if (response.data.status === 'ok') {
                    vm.code_sent[vm.last_verification_type] = true;
                    vm.messages = response.data.messages;
                } else {
                    vm.errors = response.data.errors;
                }
            });
        },

        verifyAccount: function(type) {
            var vm = this;
            vm.last_verification_type = type;
            vm.busy = true;

            this.$http.post('/plugins/AccountVerifier/ajax.php', {
                code: this.account_verifier.code[type],
                action: 'verify',
                type: type
            }).then(function (response) {
                vm.busy = false;
                if (response.data.status === 'ok') {
                    vm.account_verifier.verified[vm.last_verification_type] = true;
                    vm.messages = response.data.messages;
                    $('#emailAccountVerify').slideUp();
                } else {
                    vm.errors = response.data.errors;
                }
            });
        },

        hasField: function (field) {
            try {
                return eval('this.' + field);
            } catch(err) {
                if (err instanceof ReferenceError) {
                    return false;
                }
            }
        },

        notesLength: function (max_length) {
            if (parseInt(max_length, 10) - parseInt($('#orderNotes').val().length, 10) <= 0) {
                $('#orderNotes').val($('#orderNotes').val().substring(0, max_length));
            }
            $('.countdown').text(parseInt(max_length, 10) - parseInt($('#orderNotes').val().length, 10) + " characters remaining");
        },

        clearError: function (field) {

            let split = field.split('.'),
                vm = this;


            if(typeof split != 'undefined' && split.length) {

                let val1 = split[0],
                    val2 = split[1],
                    val3 = split[2],
                    val4 = split[3],
                    val5 = split[4];

                try {
                    if (typeof val5 != 'undefined') {
                        vm[val1][val2][val3][val4][val5] = 0;
                    } else if (typeof val4 != 'undefined') {
                        vm[val1][val2][val3][val4] = 0;
                    } else if (typeof val3 != 'undefined') {
                        vm[val1][val2][val3] = 0;
                    } else if (typeof val2 != 'undefined') {
                        vm[val1][val2] = 0;
                    }
                }catch(e) {

                }

            }


        },

        // Handle the remove item button press
        removeItem: function (item) {
            if (window.confirm('Are you sure you want to delete this item?')) {
                item.quantity = 0;
                this.callUpdate('update_qty');
            } else {
                this.$http.get('/shop/checkout/ajax.php?action=get_basket_item_qty&ajax&id=' + item.id).then(function (response) {
                    if (response.data.status === 'ok') {
                        item.quantity = response.data.quantity;
                    }
                });
            }
        },

        changeStock: function (item) {
            if(item.quantity > 0) {
                this.callUpdate('update_qty', 'item_' + item.id);
            }
        },

        updateStock: function (item) {

            if(item.quantity < 1) {
                this.removeItem(item);
            }

        },

        validateCoupon: function () {
            if (this.basket.coupon_code !== '') {
                this.callUpdate('validate_coupon');
            }
        },

        shippingTrigger: function () {
            if (this.hasField('errors.address')) {
                this.errors.address.shipping = [];
            }
            this.callUpdate('change_shipping_state');
        },

        setPafAddress: function (type) {
            var address = this.paf_address[type].split(',');
            this.basket.address[type].address1 = address[0].replace('|', ',').trim();
            if (address[2] !== undefined) {
                this.basket.address[type].address2 = address[1].replace('|', ',').trim();
                this.basket.address[type].city = address[2].trim();
            } else {
                this.basket.address[type].address2 = '';
                this.basket.address[type].city = address[1].replace('|', ',').trim();
            }
            //this.callUpdate('store_details');
        },

        hasStates: function (type) {
            if (typeof this.state_list[type] === 'undefined') {
                return 0;
            }
            return Object.keys(this.state_list[type]).length;
        },

        hasPostcodes: function (type) {

            if(typeof this.has_postcodes === 'undefined') {
                return false;
            }

            if(typeof this.has_postcodes[type] === 'undefined') {
                return false;
            }

            return true;
        },

        hasAddresses: function (type) {
            if (typeof this.address_list[type] === 'undefined') {
                return 0;
            }
            return Object.keys(this.address_list[type]).length;
        },

        triggerPAF: function (type) {
            var vm = this;
            vm.last_paf_trigger = type;
            vm.busy = true;

            this.$http.post('/core/includes/ajax_postcode.php', {
                postcode: this.basket.address[type].postcode,
                as_json: true
            }).then(function (response) {
                vm.busy = false;
                var passed_in_addresses = [];
                for(var index in response.data.addresses){
                    if(response.data.addresses.hasOwnProperty(index)){
                        passed_in_addresses.push(response.data.addresses[index].display_name);
                    }
                }
                vm.address_list[vm.last_paf_trigger] = passed_in_addresses;
                // We need to ensure that paf_address for address is updated so we reset it
                vm.paf_address[vm.last_paf_trigger] = false;
                vm.paf_address[vm.last_paf_trigger] = '';
                vm.paf_addresses = response.data.addresses;
            });
        },

        triggerTooltip: function (type) {
            var vm = this;
            vm.$nextTick(function () {
                $('.tooltipContent').stop(true,true).fadeToggle();
            });
        },

        // Ajax action for managing changes on basket
        callUpdate: function (action, focus_on) {
            var vm = this;

            this.$http.post('/shop/checkout/ajax.php', {
                ajax: true,
                action: action,
                basket: this.basket,
                cardholder_password: this.cardholder_password,
                terms: this.terms,
                newsletter: this.newsletter
            }, {
                before: function(request) {
                    vm.busy = true;
                    // abort previous request, if exists
                    if (this.previousRequest) {
                        this.previousRequest.abort();
                    }
                    // set previous request on Vue instance
                    this.previousRequest = request;
                }
            }).then(function (response) {
                if (response.data.status === 'ok') {
                    vm.messages = response.data.messages;
                    vm.errors = response.data.errors;

                    // If country was changed and details were stored => update state list
                    if (action === 'store_details') {
                        vm.state_list = response.data.state_list;
                        if (!vm.hasStates('billing')) {
                            vm.basket.address.billing.state = '';
                        }
                        if (!vm.hasStates('billing')) {
                            vm.basket.address.shipping.state = '';
                        }
                    }

                    vm.has_postcodes = response.data.has_postcodes;
                    vm.basket = response.data.basket;
                    vm.busy = false;

                    EventBus.$emit('receiveBasketUpdate', vm.basket);
                    vm.$nextTick(function () {
                        if (focus_on !== 'undefined') {
                            document.getElementById(focus_on).focus();
                        }
                    });
                } else {
                    if (response.data.status === 'proceed') {
                        window.location.href = response.data.data.url;
                    } else {
                        vm.errors = response.data.errors;
                        // Depending on the customer phone number, show / hide verification block
                        if (action === 'try_checkout') {
                            vm.basket.verify_email = response.data.verify_email;
                            vm.basket.verify_phone = response.data.verify_phone;
                        }
                        vm.$nextTick(function () {

                            // Find the first error and scroll to it
                            var off_top = 0,
                                first_error;

                            if ($('.checkoutForm .errorWrap').length) {

                                // Find the first error
                                first_error = $('.errorWrap').eq(0);

                                // Calculate offset to scroll up to
                                off_top = first_error.offset().top - 20;

                                // If mobile and fixed header, move up further so the sticky header doesn't cover the notification
                                if (matchesMediaQuery(0, 'flyout') && $('#header').length && $('.fixedFlyout').length) {
                                    off_top -= $('#header').outerHeight();
                                }

                                // Scroll to error message
                                $('html, body').delay(200).animate({
                                    scrollTop: off_top
                                }, 800);
                            }

                        });
                    }

                }
            }).finally(function() {
                vm.busy = false;
            });
        }
    }
});



$(document).ready(function () {

    'use strict';


    // Disable enter
    $('.checkoutForm').on('keypress', function (e) {
        if (e.which === 13) {
            return false;
        }
    });

    /*
     * Add to basket
     */
    if ($('.addedToBasket').length && $('.errorAddingToBasket').length) {
        $('#addToBag').on('click', function (e) {
            e.preventDefault();

            var data = $('#addtobasket').serialize() + '&ajax=true';
            $.ajax({
                type: 'post',
                url: '/shop/assessment.php',
                data: data,
                success: function (response) {

                    addItemToBasket();

                }
            });

        });
    }

}); // document ready


window.addItemToBasket = function() {

    'use strict';

    var data = $('#addtobasket').serialize();
    data += '&ajax=true&add-bag=true';


    $.ajax({
        type: 'post',
        url: '/shop/addtobasket.php',
        data: data,
        dataType: 'json',
        success: function (response) {
            if (response.status === 'ok') {
                if (response.url !== '') {
                    window.location.href = response.url;
                } else {
                    $('.addedToBasket').slideDown();
                    window.vue_environment.updateMiniBasket();
                }
            } else {
                if (response.error === 'size') {
                    $('.errorAddingToBasket').slideDown();
                    $('.itemInputWrap .sbHolder').addClass('inputError');
                } else if (response.error === 'nhs_items') {
                    $('.errorAddingToBasketNHS').slideDown();
                    $('.itemInputWrap .sbHolder').addClass('inputError');
                }
            }
        }
    });
}
