Vue.component('patientProfile', {

    props: [
        'patientData',
        'routes',
        'events',
    ],

    data: function() {
        return {
            component: 'profile',
            patient: {},
            tabs: {
                profile: {
                    name: 'Profile'
                },
                track: {
                    name: 'Track'
                },
            },
            activeTab: 'profile',
            addNote: false,
            addNoteParams: {},
            editTreatment: false,
            treatment: {},
            eventIndex: 0,
            deliveryMethods: [],
            orderParentId: null,
            siteUrl: '',
            showBasketBuilder: false,
            showReview: false,
            reviewId: null,
            ready: {
                // profile column A
                orders: true,          // render immediately
                details: true,         // render immediately
                treatmentPlan: true,
                subscriptions: true,
                attributes: true,
                files: true,
                consultations: true,
                // profile column B
                flags: true,
                notes: true,
                reviews: true,
                messages: true,
                // track tab
                weight: false,
                bp: false,
                eventlog: false,
            },
            bootstrapAttributes:
                (typeof window !== 'undefined' &&
                    window.bootstrap &&
                    window.bootstrap.attributes &&
                    Object.keys(window.bootstrap.attributes).length > 0)
                    ? window.bootstrap.attributes
                    : null,
            bootstrapFetchInFlight: false,
            bootstrapFetchedOnce: false,
        };
    },

    mounted: function () {
        this.init();
        this.fetchBootstrap();                // <-- load the initial payload once
    },

    watch: {
        events(stack) {
            // Because there may be more than one event at a time, loop through new events
            for (let i = this.eventIndex; i < stack.length; i++) {
                let event = stack[i];
                if (event.name === 'addNoteClosed') {
                    this.addNote = false;
                }
                if (event.name === 'editTreatmentClosed') {
                    this.editTreatment = false;
                    this.treatment = {};
                }
                if (event.name === 'initAddNote') {
                    this.addNote = true;
                    this.addNoteParams = event.data;
                }
                if (event.name === 'initBasketBuilder') {
                    this.showBasketBuilder = true;
                    this.orderParentId = event.data.orderId;
                }
                if (event.name === 'initEditTreatment') {
                    this.editTreatment = true;
                    this.treatment = event.data.treatment;
                }
                if (event.name === 'ordersLoaded') {
                    this.bindAddNoteAction();
                    this.bindBasketBuilderAction();
                }
                if (event.name === 'reviewsLoaded') {
                    this.bindEditReviewAction();
                }
                if (event.name === 'treatmentsLoaded') {
                    this.bindEditTreatmentAction();
                }
                if (event.name === 'initReview') {
                    this.showReview = true;
                    this.reviewId = event.data.reviewId;
                }
            }
            // Update event index so that we don't process already processed events
            this.eventIndex = stack.length;
        }
    },

    methods: {
        fetchBootstrap() {
            const url = this.routes && this.routes['admin-patient-profile-bootstrap'];
            if (!url) return;

            const hasInlineBootstrap =
                window.PatientProfileBootstrap &&
                window.PatientProfileBootstrap.responses &&
                typeof window.PatientProfileBootstrap.responses === 'object' &&
                Object.keys(window.PatientProfileBootstrap.responses).length > 0;

            const performRequest = () => {
                if (this.bootstrapFetchInFlight) return;
                this.bootstrapFetchInFlight = true;

                this.$http.post(url, {})
                    .then(({ data }) => {
                        if (data && typeof data === 'object') {
                            this.applyBootstrap(data);
                        }
                    })
                    .catch(() => {})
                    .finally(() => {
                        this.bootstrapFetchInFlight = false;
                        this.bootstrapFetchedOnce = true;
                    });
            };

            if (!hasInlineBootstrap) {
                performRequest();
                return;
            }

            // have inline payload; ensure component sees it immediately
            this.applyBootstrap(window.PatientProfileBootstrap);
            this.bootstrapFetchedOnce = true;

            // refresh in background for latest data
            setTimeout(() => performRequest(), 0);
        },
        applyBootstrap(payload) {
            if (!payload || typeof payload !== 'object') {
                return;
            }

            const target = (this.bootstrap && typeof this.bootstrap === 'object') ? this.bootstrap : {};
            if (!this.bootstrap || typeof this.bootstrap !== 'object') {
                this.bootstrap = target;
            }

            const assignReactive = (obj, key, value) => {
                if (typeof this.$set === 'function') {
                    this.$set(obj, key, value);
                } else {
                    obj[key] = value;
                }
            };

            Object.keys(payload).forEach((key) => {
                if (key === 'responses' && payload.responses && typeof payload.responses === 'object') {
                    if (!target.responses || typeof target.responses !== 'object') {
                        assignReactive(target, 'responses', {});
                    }
                    const responses = target.responses;
                    Object.keys(payload.responses).forEach((respKey) => {
                        assignReactive(responses, respKey, payload.responses[respKey]);
                    });
                } else {
                    assignReactive(target, key, payload[key]);
                }
            });

            if (typeof window !== 'undefined') {
                window.bootstrap = target;
                window.PatientProfileBootstrap = target;
            }
        },
        init() {
            this.patient = this.patientData;

            this.bindAddNoteAction();
            this.bindEditTreatmentAction();
            this.bindBasketBuilderAction();
            this.bindEditReviewAction();
        },
        setTab(tabName) {
            this.activeTab = tabName;

            // When user opens the Track tab, mount those cards lazily too
            if (tabName === 'track') {
                const trackOrder = ['weight','bp','eventlog'];
                let j = 0;
                const tick2 = () => {
                    if (j >= trackOrder.length) return;
                    this.$set(this.ready, trackOrder[j++], true);
                    (window.requestIdleCallback ? requestIdleCallback(tick2) : setTimeout(tick2, 60));
                };
                tick2();
            }
        },
        emitEvent(name, data) {
            this.$parent.emitEvent(name, data)
        },
        bindAddNoteAction() {
            let vm = this;
            vm.$nextTick(function () {
                $('.addPatientNoteButton').mtcOverlay({
                    onClose() {
                        tinyMCE.remove('#patientNotesInput');
                        vm.emitEvent('addNoteClosed');
                    },
                    onOpen() {
                        vm.$nextTick(function () {
                            simpleTinymceNew($('#patientNotesInput'), {
                                width: '100%',
                                height: 500,
                                setup: function(el) {
                                    el.on('init', function(evt) {
                                        vm.$nextTick(function () {
                                            $(window).trigger('resize.overlay');
                                        });
                                    });
                                }
                            });
                        });
                    }
                });
            });
        },
        bindBasketBuilderAction() {
            let vm = this;
            vm.$nextTick(function () {
                $('.addOrderButton').mtcOverlay({
                    onClose() {
                        vm.emitEvent('hideBasketBuilder');
                    },
                });
            });
        },
        bindEditTreatmentAction() {
            let vm = this;
            vm.$nextTick(function () {
                $('.editPatientTreatmentButton').mtcOverlay({
                    onClose() {
                        vm.emitEvent('editTreatmentClosed');
                    },
                    onOpen() {

                    }
                });
            });
        },
        bindEditReviewAction() {
            let vm = this;
            vm.$nextTick(function () {
                $('.editReviewButton').mtcOverlay({
                    onClose() {
                        vm.emitEvent('hideReview');
                    },
                });
            });
        },
    },
});
