Vue.component('patientEventLog', {
    props: ['routes','events','initialEvents','initialTypes','initialImageExtensions'],

    data() {
        const initialEventsProvided = Array.isArray(this.initialEvents);
        const events = initialEventsProvided ? this.initialEvents.slice() : [];
        const types = (this.initialTypes && typeof this.initialTypes === 'object') ? { ...this.initialTypes } : {};
        const imgs  = Array.isArray(this.initialImageExtensions) ? this.initialImageExtensions.slice() : [];
        const hasInitialData = events.length > 0 || Object.keys(types).length > 0;
        return {
            records: events,
            filteredRecords: events.slice(),
            loading: false,
            display: 5,
            deleteIndex: -1,
            showingAll: false,
            types: types,
            filterOpen: false,
            filterApplied: false,
            imageExtensions: imgs,
            filter: { types: [], id: '' },
            record: {},
            logEventOpen: false,
            eventIndex: 0,
            hasLoaded: hasInitialData,
        };
    },

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

    computed: {
        canShowAll() {
            const list = Array.isArray(this.records) ? this.records : [];
            if (!list.length) return false;
            if (this.showingAll) return false;
            if (this.filterApplied) return false;
            return list.length > this.display;
        },
        filterTypes() { return this.filter.types; },
        filterID() { return this.filter.id; },
    },

    watch: {
        initialEvents: {
            immediate: true,
            handler(list) {
                if (!Array.isArray(list)) return;
                this.records = list.slice();
                this.filteredRecords = list.slice();
                this.hasLoaded = true;
                this.loading = false;
                this.runFilter();
                this.bindEventLogModal();
            }
        },
        initialTypes: {
            immediate: true,
            handler(map) {
                if (map && typeof map === 'object') {
                    this.types = { ...map };
                }
            }
        },
        initialImageExtensions: {
            immediate: true,
            handler(list) {
                if (Array.isArray(list)) {
                    this.imageExtensions = list.slice();
                }
            }
        },
        events(stack) {
            for (let i = this.eventIndex; i < stack.length; i++) {
                const e = stack[i];
                if (
                    e.name === 'bpTrackUpdated' ||
                    e.name === 'treatmentSaved' ||
                    e.name === 'treatmentDeleted' ||
                    e.name === 'flagsChanged' ||
                    e.name === 'weightTrackUpdated'
                ) {
                    this.load(true);
                }
            }
            this.eventIndex = stack.length;
        },
        filterTypes() { this.runFilter(); },
        filterID() { this.runFilter(); },
    },

    methods: {
        init() {
            if (this.hasLoaded) {
                this.runFilter();
                this.bindEventLogModal();
                return;
            }
            this.load(true);
        },

        load(force = false) {
            if (!force && this.loading) {
                return;
            }
            const vm = this;

            const cached = (!force && this.consumeBootstrap)
                ? this.consumeBootstrap('admin-patient-event-log-load')
                : null;
            if (cached) {
                const events = Array.isArray(cached.events) ? cached.events : [];
                const types  = (cached && typeof cached.types === 'object') ? cached.types : {};
                const imgs   = Array.isArray(cached.imageExtensions) ? cached.imageExtensions : [];

                vm.records = events;
                vm.types = { ...types };
                vm.imageExtensions = imgs.slice();
                vm.loading = false;
                vm.hasLoaded = true;

                if (typeof vm.cacheBootstrap === 'function') {
                    vm.cacheBootstrap('admin-patient-event-log-load', {
                        events: events.slice(),
                        types: { ...types },
                        imageExtensions: imgs.slice(),
                    });
                }

                vm.bindEventLogModal();
                vm.runFilter();
                return;
            }

            this.loading = true;

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

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

                    const events = Array.isArray(payload?.events) ? payload.events : [];
                    const types  = (payload && typeof payload.types === 'object') ? payload.types : {};
                    const imgs   = Array.isArray(payload?.imageExtensions) ? payload.imageExtensions : [];

                    vm.records = events;              // always array
                    vm.types = { ...types };
                    vm.imageExtensions = imgs.slice();
                    vm.loading = false;
                    vm.hasLoaded = true;

                    if (typeof vm.cacheBootstrap === 'function') {
                        vm.cacheBootstrap('admin-patient-event-log-load', {
                            events: events.slice(),
                            types: { ...types },
                            imageExtensions: imgs.slice(),
                        });
                    }

                    vm.bindEventLogModal();
                    vm.runFilter();
                })
                .catch((err) => {
                    console.error('Event log load failed:', err);
                    this.loading = false;
                    this.records = [];
                    this.filteredRecords = [];
                });
        },

        typeName(type) {
            // handle empty, numeric, string keys
            if (type === null || type === undefined || (typeof type === 'string' && type.trim() === '')) return '-';
            return this.types?.[type] ?? '-';
        },

        showAll() {
            this.showingAll = true;
            this.bindEventLogModal();
        },

        bindEventLogModal() {
            const vm = this;
            this.$nextTick(function () {
                $('.eventLogModalButton').mtcOverlay({
                    onClose() {
                        vm.record = {};
                        vm.logEventOpen = false;
                    },
                });
            });
        },

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

        viewRecord(record) {
            this.record = record || {};
            this.logEventOpen = true;
        },

        toggleFilter() {
            this.filterOpen = !this.filterOpen;
        },

        showRow(index) {
            if (this.showingAll) return true;
            if (this.filterApplied) return true;
            return (index + 1) <= this.display;
        },

        runFilter() {
            this.filterApplied = false;

            const list = Array.isArray(this.records) ? this.records : [];
            const byType = this.filterByType(list);
            this.filteredRecords = this.filterByID(byType);
        },

        filterByType(records) {
            const types = Array.isArray(this.filter?.types) ? this.filter.types : [];
            if (!types.length) return Array.isArray(records) ? records.slice() : [];

            const out = [];
            if (Array.isArray(records)) {
                for (let i = 0; i < records.length; i++) {
                    if (types.includes(records[i].subject)) out.push(records[i]);
                }
            }
            this.filterApplied = true;
            return out;
        },

        filterByID(records) {
            const id = (this.filter?.id ?? '').toString().trim();
            if (id === '') return Array.isArray(records) ? records.slice() : [];

            const out = [];
            if (Array.isArray(records)) {
                for (let i = 0; i < records.length; i++) {
                    if (String(records[i].loggable_id) === id) out.push(records[i]);
                }
            }
            this.filterApplied = true;
            return out;
        },

        isImage(extension) {
            const exts = Array.isArray(this.imageExtensions) ? this.imageExtensions : [];
            return exts.includes(extension);
        },

        normaliseDetailsKey(key) {
            return String(key || '').split('_').join(' ');
        },

        normaliseDetailsValue(value) {
            try { return JSON.stringify(value, null, 2); }
            catch { return String(value); }
        },
    },
});
