// Fresh factory every time — avoids sharing a single object reference
function makeDefaultReview() {
    return {
        id: null,
        status: 'unscheduled',
        member_id: null,
        user_id: null,     // align with template/controller
        form_id: null,
        category_id: null,
        medium: null,
        type: null,
        notes: '',
        due_date: '',
    };
}

Vue.component('editReviewForm', {

    props: [
        'routes',
        'events',
        'reviewId',
        'isInline',
        'patientData',
        'parent',
    ],

    data() {
        return {
            component: 'review',
            review: makeDefaultReview(),
            loading: false,
            errors: {},
            success: false,
            reviewTypeIndex: null,
            dateOption: '',
            patient: {},
            patientQuery: '',
            patients: [],
            categories: [],
            reviewTypes: [],
            types: [],
            forms: [],
            users: [],
            mediums: [],
            statuses: [],
            assessments: [],
            dateOptions: [],
            showReview: false,
            eventIndex: 0,
            currentReviewId: null, // <-- NEW: source of truth for the opened review
        };
    },

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

    watch: {
        reviewTypeIndex(index) {
            if (index === null) {
                // reset but keep selected patient if any
                const member_id = this.patient?.id ?? this.review?.member_id ?? null;
                this.review = Object.assign(makeDefaultReview(), { member_id });
                return;
            }
            const rt = (Array.isArray(this.reviewTypes) && this.reviewTypes[index]) || null;
            if (!rt) return;
            // keep existing review, just set fields from the selected type
            this.$set(this.review, 'form_id', rt.form_id ?? null);
            this.$set(this.review, 'category_id', rt.category_id ?? null);
            this.$set(this.review, 'type', rt.type ?? null);
            this.$set(this.review, 'medium', rt.medium ?? null);
        },

        dateOption(date) {
            // radio “Due in …” writes directly into due_date
            this.$set(this.review, 'due_date', date || '');
        },

        patientData(patient) {
            this.patient = patient || {};
            if (this.patient && this.patient.id) {
                this.$set(this.review, 'member_id', this.patient.id);
            }
        },

        events(stack) {
            for (let i = this.eventIndex; i < stack.length; i++) {
                const event = stack[i];

                if (event.name === 'initReview') {
                    this.showReview = true;
                    // ---- IMPORTANT: use the id from the event (can be null for "new") ----
                    const idFromEvent = (event.data && 'reviewId' in event.data) ? event.data.reviewId : null;
                    this.currentReviewId = idFromEvent;   // keep it
                    this.loadReview(idFromEvent);         // and load with it
                }
                if (event.name === 'hideReview') {
                    this.showReview = false;
                }
            }
            this.eventIndex = stack.length;
        },

        // React to medium changes safely
        reviewMedium(newMedium) {
            if (!newMedium) return;
            if (newMedium === 'video' || newMedium === 'phone') {
                this.$set(this.review, 'status', 'unscheduled');
            } else if (newMedium === 'online') {
                this.$set(this.review, 'status', 'pending');
            }
        },
    },

    computed: {
        showStatus() {
            return !!(this.review && this.review.medium);
        },
        reviewMedium() {
            return this.review ? this.review.medium : null;
        }
    },

    methods: {
        init() {
            if (!this.isInline) return;

            this.showReview = true;
            const initialId = (typeof this.reviewId !== 'undefined') ? this.reviewId : null;
            this.currentReviewId = initialId;
            this.loadReview(initialId);
        },

        store() {
            if (this.loading) return;

            this.errors = {};
            this.success = false;
            this.loading = true;

            const vm = this;

            // sync datepicker -> model (legacy datepicker safety)
            this.review.due_date = $('#due_date').val() || this.review.due_date || '';
            // ensure member_id is set
            this.review.member_id = this.patient?.id ?? this.review.member_id ?? null;

            this.$http.post(this.routes['admin-reviews-store'], { ...(this.review || {}) })
                .then((response) => {
                    this.loading = false;

                    let data = response && response.data;
                    if (typeof data === 'string') {
                        try { data = JSON.parse(data); } catch (e) { data = {}; }
                    }

                    if (data.errors) {
                        vm.errors = data.errors;
                        return;
                    }

                    if (data.success) {
                        vm.success = data.success;

                        // normalize returned review or keep existing one
                        const incoming = (data.review && typeof data.review === 'object') ? data.review : {};
                        vm.review = vm._normalizeReview(incoming);
                        vm.currentReviewId = vm.review.id ?? null;

                        // let parent refresh lists, etc.
                        vm.emitEvent('reviewsUpdated');
                    }
                })
                .catch(() => {
                    this.loading = false;
                    this.errors = this.errors || {};
                    this.errors.general = 'Unable to save. Please try again.';
                });
        },

        searchPatients() {
            const vm = this;
            vm.success = false;
            vm.successText = '';
            vm.orderId = 0;

            this.$http.post(this.routes['admin-patients-search'], { query: this.patientQuery })
                .then((response) => {
                    let data = response && response.data;
                    if (typeof data === 'string') {
                        try { data = JSON.parse(data); } catch (e) { data = {}; }
                    }
                    if (data && data.success) {
                        vm.patients = data.patients || [];
                        return;
                    }
                    vm.errors = data && data.errors ? data.errors : {};
                })
                .catch(() => {
                    vm.errors = { general: 'Search failed. Please try again.' };
                });
        },

        loadReview(id) {
            const vm = this;
            vm.success = false;
            vm.successText = '';

            // Prefer explicit id argument; fall back to currentReviewId; then to prop
            const reviewId = (typeof id !== 'undefined')
                ? id
                : (this.currentReviewId !== null ? this.currentReviewId
                    : (typeof this.reviewId !== 'undefined' ? this.reviewId : null));

            // If creating new, clear the form immediately for UX
            if (reviewId === null) {
                vm.review = makeDefaultReview();
                vm.assessments = [];
            }

            this.$http.post(this.routes['admin-reviews-load-review'], { id: reviewId })
                .then((response) => {
                    let data = response && response.data;
                    if (typeof data === 'string') {
                        try { data = JSON.parse(data); } catch (e) { data = {}; }
                    }

                    // lists
                    vm.categories  = data?.categories  || [];
                    vm.reviewTypes = data?.reviewTypes || [];
                    vm.types       = data?.types       || {};
                    vm.forms       = data?.forms       || [];
                    vm.mediums     = data?.mediums     || {};
                    vm.statuses    = data?.statuses    || {};
                    vm.users       = data?.users       || [];
                    vm.dateOptions = data?.dateOptions || {};

                    // review payload (may be empty for new review)
                    const incoming = (data && typeof data.review === 'object') ? data.review : {};
                    vm.review = vm._normalizeReview(incoming);
                    vm.assessments = Array.isArray(vm.review.assessments) ? vm.review.assessments : [];

                    // For a brand-new review, prefill prescriber from lastReview if provided
                    if (reviewId === null && data.lastReview) {
                        vm.review.user_id = data.lastReview.user_id ?? vm.review.user_id;
                    }

                    // When editing, flatten patient details for summary
                    if (reviewId && vm.review.member) {
                        const m  = vm.review.member;
                        const ab = m.address_billing || {};
                        vm.patient = {
                            ...m,
                            firstname: ab.firstname || m.firstname,
                            lastname : ab.lastname  || m.lastname,
                            address1 : ab.address1,
                            address2 : ab.address2,
                            city     : ab.city,
                            postcode : ab.postcode,
                        };
                    } else if (vm.patientData && vm.patientData.id) {
                        // If patient passed in props, ensure member_id is set
                        vm.patient = vm.patientData;
                        vm.review.member_id = vm.patient.id;
                    }

                    // Update our source-of-truth id after load
                    vm.currentReviewId = vm.review.id ?? null;
                })
                .catch(() => {
                    // Fall back to a safe empty review so template/watchers don't explode
                    vm.review = makeDefaultReview();
                    vm.assessments = [];
                    vm.currentReviewId = null;
                });
        },

        // Ensure all keys exist and formats match the UI expectations
        _normalizeReview(incoming) {
            const base = makeDefaultReview();
            const out = Object.assign({}, base, (incoming || {}));
            out.due_date = out.due_date || '';

            if (typeof out.notes === 'undefined' || out.notes === null) out.notes = '';
            if (typeof out.medium === 'undefined') out.medium = null;
            if (typeof out.type === 'undefined') out.type = null;
            if (typeof out.status === 'undefined' || !out.status) out.status = 'unscheduled';

            return out;
        },

        selectPatient(patient) {
            this.patient = patient || {};
            this.$set(this.review, 'member_id', this.patient?.id ?? null);
            this.patients = [];
            this.patientQuery = '';
        },

        getPatientProfileURL(id) {
            return this.routes['admin-patients-profile'].replace('---id---', id);
        },

        emitEvent(name, data) {
            this.$parent.emitEvent(name, data);
        },
    },
});
