<template>
    <div :class="type + 'Address'" v-show="visible">
        <!-- Country -->
        <div class="row">
            <label :for="idFor('Country')">
                Country<sup>*</sup>
            </label>
            <div class="inputWrap">
                <chosen
                    :options="countries"
                    placeholder="Select country"
                    :value="address.country"
                    @input="onCountryChange"
                    class="selectCountry"
                    :id="idFor('Country')"
                    :name="type + '_country'"
                />
            </div>
        </div>

        <!-- Phone Number (billing only) -->
        <div
            v-if="isBilling"
            class="row"
            :class="{
                'errorWrap showError': hasError('info.contact_no') || hasError('info.phone_prefix')
            }"
        >
            <label for="phoneNo">
                Phone number<sup>*</sup>
            </label>
            <div class="inputWrap">
                <input
                    maxlength="20"
                    type="tel"
                    name="cardholder_phone_number"
                    id="phoneNo"
                    @focus="clearError('info.contact_no')"
                    :value="basket.info.contact_no"
                    @input="updateField('info.contact_no', $event.target.value)"
                    class="text"
                />
                <input
                    type="hidden"
                    name="cardholder_phone_prefix"
                    id="phonePrefix"
                    :value="basket.info.phone_prefix"
                    @focus="clearError('info.phone_prefix')"
                    class="text prefix"
                    autocomplete="off"
                    readonly
                />
            </div>
            <div class="validationMessage" v-if="hasError('info.contact_no')">
                <span>{{ errorText('info.contact_no') }}</span>
            </div>
            <div class="validationMessage" v-if="hasError('info.phone_prefix')">
                <span>{{ errorText('info.phone_prefix') }}</span>
            </div>
        </div>

        <!-- Address Line 1 -->
        <div
            class="row"
            :class="{ 'errorWrap showError': hasError(fieldPath('address1')) }"
        >
            <label :for="idFor('Address1')">
                Address Line 1<sup>*</sup>
            </label>
            <div class="inputWrap">
                <input
                    maxlength="100"
                    type="text"
                    @focus="clearError(fieldPath('address1'))"
                    :name="type + '_address_line_1'"
                    :id="idFor('Address1')"
                    :value="address.address1"
                    @input="updateField(fieldPath('address1'), $event.target.value)"
                    class="text"
                />
            </div>
            <div class="validationMessage" v-if="hasError(fieldPath('address1'))">
                <span>{{ errorText(fieldPath('address1')) }}</span>
            </div>
        </div>

        <!-- Address Line 2 -->
        <div
            class="row"
            :class="{ 'errorWrap showError': hasError(fieldPath('address2')) }"
        >
            <label :for="idFor('Address2')">
                Address Line 2
            </label>
            <div class="inputWrap">
                <input
                    maxlength="100"
                    type="text"
                    :name="type + '_address_line_2'"
                    :id="idFor('Address2')"
                    @focus="clearError(fieldPath('address2'))"
                    :value="address.address2"
                    @input="updateField(fieldPath('address2'), $event.target.value)"
                    class="text"
                />
            </div>
            <div class="validationMessage" v-if="hasError(fieldPath('address2'))">
                <span>{{ errorText(fieldPath('address2')) }}</span>
            </div>
        </div>

        <!-- City -->
        <div
            class="row"
            :class="{ 'errorWrap showError': hasError(fieldPath('city')) }"
        >
            <label :for="idFor('City')">
                City<sup>*</sup>
            </label>
            <div class="inputWrap">
                <input
                    maxlength="39"
                    type="text"
                    :name="type + '_city'"
                    :id="idFor('City')"
                    @focus="clearError(fieldPath('city'))"
                    :value="address.city"
                    @input="updateField(fieldPath('city'), $event.target.value)"
                    class="text"
                />
            </div>
            <div class="validationMessage" v-if="hasError(fieldPath('city'))">
                <span>{{ errorText(fieldPath('city')) }}</span>
            </div>
        </div>

        <!-- Postcode -->
        <div
            class="row"
            :class="{ 'errorWrap showError': hasError(fieldPath('postcode')) }"
        >
            <label :for="idFor('Postcode')">
                Postcode/Zip<sup v-show="hasPostcodesComputed">*</sup>
            </label>
            <div class="inputWrap">
                <input
                    maxlength="10"
                    type="text"
                    :name="type + '_postcode'"
                    :id="idFor('Postcode')"
                    @focus="clearError(fieldPath('postcode'))"
                    :value="address.postcode"
                    @input="updateField(fieldPath('postcode'), $event.target.value)"
                    class="text"
                />
            </div>
            <div class="validationMessage" v-if="hasError(fieldPath('postcode'))">
                <span>{{ errorText(fieldPath('postcode')) }}</span>
            </div>
        </div>

        <!-- Country Error -->
        <div
            class="row country"
            :class="{ 'errorWrap showError': hasError(fieldPath('country')) }"
        >
            <div class="validationMessage" v-if="hasError(fieldPath('country'))">
                <span>{{ errorText(fieldPath('country')) }}</span>
            </div>
        </div>

        <!-- State (if applicable) -->
        <div
            class="row"
            :class="[type + 'State', { 'errorWrap showError': hasError(fieldPath('state')) }]"
            v-show="hasStatesComputed"
        >
            <label class="country" :for="idFor('State')">
                State<sup>*</sup>
            </label>
            <div class="inputWrap">
                <select
                    :name="type + '_state'"
                    :value="address.state"
                    @change="onStateChange"
                    :id="idFor('State')"
                >
                    <option value="">Choose State</option>
                    <option
                        v-for="(state, key) in statesForType"
                        :key="key"
                        :value="key"
                    >
                        {{ state }}
                    </option>
                </select>
            </div>
            <div class="validationMessage" v-if="hasError(fieldPath('state'))">
                <span>{{ errorText(fieldPath('state')) }}</span>
            </div>
        </div>

        <!-- Reason for different shipping address (shipping only) -->
        <div
            v-if="isShipping"
            class="row"
            :class="{ 'errorWrap showError': hasError(fieldPath('notes')) }"
        >
            <label :for="idFor('Notes')">
                Reason for shipping to different address than billing address<sup>*</sup>
            </label>
            <div class="inputWrap">
                <textarea
                    :id="idFor('Notes')"
                    :name="type + '_notes'"
                    @focus="clearError(fieldPath('notes'))"
                    :value="address.notes"
                    @input="updateField(fieldPath('notes'), $event.target.value)"
                    class="text"
                ></textarea>
            </div>
            <div class="validationMessage" v-if="hasError(fieldPath('notes'))">
                <span>{{ errorText(fieldPath('notes')) }}</span>
            </div>
        </div>

        <!-- Ship to this address checkbox (billing only) -->
        <template v-if="isBilling">
            <div class="row alt_del checkboxRow" v-if="allowAlternateDelivery">
                <input
                    type="checkbox"
                    name="shipping_address"
                    id="shippingAddress"
                    @change="onShippingToggle"
                    :checked="basket.billing_address_used === 1"
                />
                <label for="shippingAddress">
                    Ship to this address?
                </label>
            </div>
            <input
                v-else
                type="hidden"
                name="shipping_address"
                :value="basket.billing_address_used"
            />
        </template>
    </div>
</template>

<script>
import errorMixin from '../shared/error_mixin.js';

export default {
    name: 'address-section',

    mixins: [errorMixin],

    props: {
        // 'billing' or 'shipping' — parameterises field names, ids, paths and the extra rows.
        type: {
            type: String,
            required: true,
            validator: value => ['billing', 'shipping'].includes(value)
        },
        basket: {
            type: Object,
            required: true
        },
        countries: {
            type: Object,
            default: () => ({})
        },
        stateList: {
            type: [Object, Array],
            default: () => ({ billing: {}, shipping: {} })
        },
        hasPostcodes: {
            type: [Object, Boolean],
            default: () => ({})
        },
        errors: {
            type: [Object, Array],
            default: () => ({})
        },
        allowAlternateDelivery: {
            type: Boolean,
            default: true
        }
    },

    computed: {
        isBilling() {
            return this.type === 'billing';
        },
        isShipping() {
            return this.type === 'shipping';
        },
        address() {
            return this.basket.address[this.type];
        },
        // Billing is always visible; shipping is hidden while the billing address is reused.
        visible() {
            return this.isBilling || !this.basket.billing_address_used;
        },
        statesForType() {
            return this.stateList[this.type] || {};
        },
        hasStatesComputed() {
            return this.stateList[this.type] && Object.keys(this.stateList[this.type]).length > 0;
        },
        hasPostcodesComputed() {
            return this.hasPostcodes && this.hasPostcodes[this.type];
        }
    },

    methods: {
        // e.g. type 'billing' + 'Address1' => 'billingAddress1' (matches the legacy element ids)
        idFor(suffix) {
            return this.type + suffix;
        },

        fieldPath(field) {
            return `address.${this.type}.${field}`;
        },

        clearError(path) {
            this.$emit('clear-error', path);
        },

        updateField(path, value) {
            this.$emit('update-field', { path, value });
        },

        onCountryChange(value) {
            this.updateField(this.fieldPath('country'), value);
            this.clearError(this.fieldPath('country'));
            if (this.isBilling) {
                // Trigger store details update after country change
                this.$nextTick(() => {
                    this.$emit('store-details');
                });
            } else {
                this.$emit('shipping-trigger');
            }
        },

        onStateChange(event) {
            this.updateField(this.fieldPath('state'), event.target.value);
            this.clearError(this.fieldPath('state'));
            this.$emit('store-details');
        },

        onShippingToggle(event) {
            const value = event.target.checked ? 1 : 0;
            this.updateField('billing_address_used', value);
            this.$emit('shipping-trigger');
        }
    }
};
</script>
