<template>
    <div class="quick-order-page">
        <header class="quick-order-page__header">
            <h1>Quick Order</h1>
            <p class="quick-order-page__intro">
                Add multiple products to your basket without leaving this page. Ideal for reordering.
            </p>
        </header>

        <div class="quick-order-search" role="search">
            <label for="quick-order-search-input" class="quick-order-search__label">
                Search the catalogue
            </label>
            <div class="quick-order-search__field">
                <input
                    id="quick-order-search-input"
                    ref="searchInput"
                    type="search"
                    v-model="searchTerm"
                    @input="onSearchInput"
                    @keydown.enter.prevent="onSearchEnter"
                    @keydown.esc="onSearchEscape"
                    placeholder="e.g. Regaine, ibuprofen, 5012345678900"
                    autocomplete="off"
                    class="quick-order-search__input"
                    :aria-describedby="'quick-order-search-help'"
                />
                <button
                    v-if="searchTerm.length > 0"
                    type="button"
                    class="quick-order-search__clear"
                    @click="resetSearch"
                    aria-label="Clear search"
                >&times;</button>
            </div>
            <p id="quick-order-search-help" class="quick-order-search__help">
                Search by product name, EPoS code, PLU, or EAN. Type at least 2 characters.
            </p>
        </div>

        <div
            class="quick-order-status"
            aria-live="polite"
            aria-atomic="true"
        >
            <span v-if="loading">Searching…</span>
            <span v-else-if="hasSearched && products.length > 0">
                Showing {{ products.length }} {{ products.length === 1 ? 'result' : 'results' }}<template v-if="products.length >= resultCap">, refine your search to narrow further</template>
            </span>
        </div>

        <div v-if="loading && products.length === 0" class="quick-order-loading">
            <loading-spinner></loading-spinner>
        </div>

        <div v-if="products.length > 0" class="quick-order-results">
            <div class="quick-order-results__header" role="row">
                <span></span>
                <span>Product</span>
                <span>Price</span>
                <span>Size</span>
                <span>Qty</span>
                <span></span>
            </div>
            <quick-order-row
                v-for="(product, index) in products"
                :key="product.id"
                :ref="'row-' + index"
                :product="product"
                @show-assessment-modal="showAssessmentModal"
            ></quick-order-row>
        </div>

        <div
            v-if="!loading && searchTerm.length >= 2 && products.length === 0 && hasSearched"
            class="quick-order-empty"
        >
            <p class="quick-order-empty__headline">No products match "{{ searchTerm }}"</p>
            <p class="quick-order-empty__hint">
                Double-check the spelling, or try the EPoS, PLU, or EAN code from the product packaging.
            </p>
        </div>

        <div
            v-if="!hasSearched && searchTerm.length < 2 && !loading"
            class="quick-order-intro"
        >
            <div class="quick-order-intro__tips">
                <h2 class="quick-order-intro__title">How it works</h2>
                <ol class="quick-order-intro__list">
                    <li><strong>Search</strong> for a product by name or code.</li>
                    <li><strong>Pick a size</strong> and quantity, then click Add to basket.</li>
                    <li><strong>Repeat</strong> - your basket updates instantly. Keep searching to add more.</li>
                </ol>
            </div>
            <aside class="quick-order-intro__note">
                <p>
                    <strong>Pharmacy &amp; prescription items</strong> require a short consultation before they can be added. Look for the badge next to the product name.
                </p>
            </aside>
        </div>

        <quick-order-modal
            :visible="modalVisible"
            :assessment-url="modalAssessmentUrl"
            @close="closeModal"
        ></quick-order-modal>
    </div>
</template>

<script>
import axios from 'axios';
import QuickOrderRow from './quick_order_row.vue';
import QuickOrderModal from './quick_order_modal.vue';

const RESULT_CAP = 24;

export default {
    name: 'QuickOrderPage',
    components: {
        QuickOrderRow,
        QuickOrderModal
    },
    data() {
        return {
            searchTerm: '',
            products: [],
            loading: false,
            hasSearched: false,
            searchTimeout: null,
            abortController: null,
            modalVisible: false,
            modalAssessmentUrl: '',
            resultCap: RESULT_CAP
        };
    },
    mounted() {
        this.$nextTick(() => {
            if (this.$refs.searchInput) {
                this.$refs.searchInput.focus();
            }
        });
    },
    methods: {
        onSearchInput() {
            if (this.searchTimeout) {
                clearTimeout(this.searchTimeout);
            }

            if (this.searchTerm.length < 2) {
                this.clearResults();
                return;
            }

            this.searchTimeout = setTimeout(() => {
                this.fetchResults();
            }, 300);
        },

        onSearchEnter() {
            if (this.searchTimeout) {
                clearTimeout(this.searchTimeout);
                this.searchTimeout = null;
            }

            if (this.searchTerm.length < 2) {
                return;
            }

            if (this.products.length > 0 && !this.loading) {
                this.focusFirstRow();
                return;
            }

            this.fetchResults();
        },

        onSearchEscape() {
            this.resetSearch();
        },

        resetSearch() {
            this.searchTerm = '';
            this.clearResults();
            if (this.$refs.searchInput) {
                this.$refs.searchInput.focus();
            }
        },

        focusFirstRow() {
            const row = this.$refs['row-0'];
            const instance = Array.isArray(row) ? row[0] : row;
            if (instance && typeof instance.focus === 'function') {
                instance.focus();
            }
        },

        fetchResults() {
            if (this.abortController) {
                this.abortController.abort();
            }

            this.abortController = new AbortController();
            this.loading = true;

            axios.get('/quick-order/search', {
                params: { term: this.searchTerm },
                signal: this.abortController.signal
            })
                .then(response => {
                    this.products = response.data.products || [];
                    this.hasSearched = true;
                })
                .catch(err => {
                    if (axios.isCancel(err) || err.name === 'CanceledError' || err.code === 'ERR_CANCELED') {
                        return;
                    }
                    this.products = [];
                    this.hasSearched = true;
                })
                .finally(() => {
                    this.loading = false;
                });
        },

        clearResults() {
            if (this.abortController) {
                this.abortController.abort();
            }
            this.products = [];
            this.hasSearched = false;
        },

        showAssessmentModal(data) {
            this.modalVisible = true;
            this.modalAssessmentUrl = data.assessmentUrl;
        },

        closeModal() {
            this.modalVisible = false;
        }
    },
    beforeDestroy() {
        if (this.searchTimeout) {
            clearTimeout(this.searchTimeout);
        }
        if (this.abortController) {
            this.abortController.abort();
        }
    }
};
</script>
