const reviewsSignature = function (list) {
    if (!Array.isArray(list)) {
        return '[]';
    }
    try {
        return JSON.stringify(list);
    } catch (e) {
        return String(list.length || 0);
    }
};

Vue.component('patientReviews', {
    props: ['routes','events','patientData','initialReviews'],

    data() {
        const initialProvided = Array.isArray(this.initialReviews);
        const initial = initialProvided ? this.initialReviews.slice() : [];
        return {
            patient: {},
            reviews: initial,     // keep as array
            hasLoaded: initialProvided,
            types: [],
            mediums: [],
            loading: false,
            display: 5,
            eventIndex: 0,
            component: 'reviews',
            bootstrapReviewsSignature: reviewsSignature(initial),
            reviewsEventSent: false,
        };
    },

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

    computed: {
        canLoadMore() {
            const list = Array.isArray(this.reviews) ? this.reviews : [];
            if (!list.length) return false;
            return list.length > this.display;
        }
    },

    watch: {
        initialReviews: {
            immediate: true,
            handler(list) {
                const next = Array.isArray(list) ? list : [];
                const signature = reviewsSignature(next);
                if (signature === this.bootstrapReviewsSignature) {
                    return;
                }
                this.bootstrapReviewsSignature = signature;
                this.reviews = next.slice();
                this.hasLoaded = true;
                this.loading = false;
                this.notifyReviewsLoaded();
            }
        },
        events(stack) {
            for (let i = this.eventIndex; i < stack.length; i++) {
                const event = stack[i];
                if (event.name === 'reviewsUpdated') {
                    this.load(true);
                }
            }
            this.eventIndex = stack.length;
        }
    },

    methods: {
        init() {
            this.patient = this.patientData || {};
            if (this.hasLoaded) {
                this.notifyReviewsLoaded();
                return;
            }
            this.load(true);
        },

        load(force = false) {
            if (!force && this.loading) {
                return;
            }
            const vm = this;
            const cached = (!force && this.consumeBootstrap)
                ? this.consumeBootstrap('admin-reviews-load')
                : null;
            if (cached) {
                const list = Array.isArray(cached.reviews) ? cached.reviews : [];
                const signature = reviewsSignature(list);
                const changed = signature !== vm.bootstrapReviewsSignature;
                vm.reviews = list.slice();
                vm.loading = false;
                vm.hasLoaded = true;
                if (changed) {
                    vm.bootstrapReviewsSignature = signature;
                }
                vm.notifyReviewsLoaded(changed);
                if (changed && typeof vm.cacheBootstrap === 'function') {
                    vm.cacheBootstrap('admin-reviews-load', {reviews: list.slice()});
                }
                return;
            }

            this.loading = true;

            this.$http.post(this.routes['admin-reviews-load'], {})
                .then((response) => {
                    let payload = response.data;

                    // vue-resource may return JSON as a string
                    if (typeof payload === 'string') {
                        try { payload = JSON.parse(payload); }
                        catch (e) {
                            console.error('Invalid JSON from admin-reviews-load:', e, payload);
                            payload = {};
                        }
                    }

                    const list = Array.isArray(payload?.reviews) ? payload.reviews : [];
                    const signature = reviewsSignature(list);
                    const changed = signature !== vm.bootstrapReviewsSignature;
                    vm.reviews = list.slice();
                    vm.loading = false;
                    vm.hasLoaded = true;
                    if (changed) {
                        vm.bootstrapReviewsSignature = signature;
                    }
                    vm.notifyReviewsLoaded(changed);
                    if (changed && typeof vm.cacheBootstrap === 'function') {
                        vm.cacheBootstrap('admin-reviews-load', { reviews: list.slice() });
                    }
                })
                .catch((err) => {
                    console.error('Reviews load failed:', err);
                    vm.loading = false;
                    vm.reviews = []; // avoid undefined in render
                });
        },

        loadMore() {
            this.display += 5;
            this.notifyReviewsLoaded(true);
        },

        editReviewAction(id) {
            this.emitEvent('initReview', { reviewId: id > 0 ? id : null });
        },

        emitEvent(name, data) {
            this.$parent.emitEvent(name, data);
        },
        notifyReviewsLoaded(force = false) {
            if (!this.reviewsEventSent || force) {
                this.reviewsEventSent = true;
                this.emitEvent('reviewsLoaded');
            }
        },
    },
});
