Vue.component('patientFiles', {
    props: ['routes','events','initialFiles','initialTypes','initialImageExtensions','initialToday'],

    data: function() {
        const initialFilesProvided = Array.isArray(this.initialFiles);
        const files = initialFilesProvided ? this.initialFiles.slice() : [];
        const types = (this.initialTypes && typeof this.initialTypes === 'object') ? { ...this.initialTypes } : {};
        const imgs  = Array.isArray(this.initialImageExtensions) ? this.initialImageExtensions.slice() : [];
        const today = this.initialToday || null;
        const hasInitialData = files.length > 0 || Object.keys(types).length > 0;

        return {
            records: files,
            filteredRecords: files.slice(),
            loading: false,
            hasLoaded: hasInitialData,
            editMode: false,
            errors: {},
            success: false,
            display: 5,
            defaultFileRecord: {
                id: null,
                title: '',
                type: 'file',
            },
            record: {},
            deleteIndex: -1,
            todayDate: today,
            showingAll: false,
            types: {},                // map of type code -> label
            filterOpen: false,
            filterApplied: false,
            imageExtensions: imgs,
            filter: { types: [] },
            eventIndex: 0,
        };
    },

    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;
        }
    },

    watch: {
        initialFiles: {
            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.bindImageModal();
            }
        },
        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 event = stack[i];
                if (event.name === 'bpTrackUpdated') this.load(true);
            }
            this.eventIndex = stack.length;
        },
        filterTypes () {
            this.runFilter();
        }
    },

    methods: {
        init() {
            this.record = { ...this.defaultFileRecord };
            if (this.hasLoaded) {
                this.types = (this.initialTypes && typeof this.initialTypes === 'object') ? { ...this.initialTypes } : {};
                this.imageExtensions = Array.isArray(this.initialImageExtensions) ? this.initialImageExtensions.slice() : [];
                this.runFilter();
                this.bindImageModal();
                return;
            }
            this.load(true);
        },

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

            const vm = this;

            const applyPayload = (payload) => {
                const files    = Array.isArray(payload?.files) ? payload.files : [];
                const types    = (payload && typeof payload.types === 'object') ? payload.types : {};
                const today    = payload?.todayDate ?? null;
                const imgExts  = Array.isArray(payload?.imageExtensions) ? payload.imageExtensions : [];

                vm.records         = files;
                vm.types           = { ...types };
                vm.todayDate       = today;
                vm.imageExtensions = imgExts.slice();
                vm.loading         = false;
                vm.hasLoaded       = true;

                if (typeof vm.cacheBootstrap === 'function') {
                    vm.cacheBootstrap('admin-patient-files-load', {
                        files: files.slice(),
                        types: { ...types },
                        todayDate: today,
                        imageExtensions: imgExts.slice(),
                    });
                }

                vm.bindImageModal();
                vm.runFilter();
            };

            const cached = (!force && this.consumeBootstrap)
                ? this.consumeBootstrap('admin-patient-files-load')
                : null;
            if (cached) {
                applyPayload(cached);
                return;
            }

            this.loading = true;

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

                    if (typeof payload === 'string') {
                        try { payload = JSON.parse(payload); }
                        catch (e) {
                            console.error('Invalid JSON from admin-patient-files-load:', e, payload);
                            payload = {};
                        }
                    }

                    applyPayload(payload);
                })
                .catch((err) => {
                    console.error('Files load failed:', err);
                    this.loading = false;
                    this.records = [];
                    this.filteredRecords = [];
                });
        },

        typeName(type) {
            if (!type) return '-';
            return this.types[type] ?? '-';
        },

        // IMPORTANT: always deep-clone into a plain object before binding
        editRecord(record) {
            this.editMode = true;

            if (record && typeof record === 'object') {
                // keep only fields we actually edit to avoid getters/proxies
                const plain = {
                    id: record.id ?? null,
                    title: record.title ?? '',
                    type: record.type ?? 'file'
                };
                this.record = plain;
            } else {
                this.record = { ...this.defaultFileRecord };
            }

            $('#fileDate').val(this.todayDate || '');
        },

        cancel() { this.editMode = false; },

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

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

            this.record.date_provided = $('#fileDate').val();

            const formData = new FormData();
            const fileEl = document.getElementById('patientFile');
            if (fileEl && fileEl.files && fileEl.files[0]) {
                // append the native File as 'file' — never mutate file.type
                formData.append('file', fileEl.files[0]);
            }
            // append our editable fields
            Object.keys(this.record).forEach(k => formData.append(k, this.record[k]));

            const vm = this;

            // Do NOT force Content-Type here; let the browser set the boundary
            this.$http.post(this.routes['admin-patient-files-store'], formData)
                .then((response) => {
                    let payload = response.data;
                    if (typeof payload === 'string') {
                        try { payload = JSON.parse(payload); } catch { payload = {}; }
                    }

                    if (payload.errors) {
                        vm.errors = payload.errors;
                        vm.loading = false;
                        return;
                    }
                    if (payload.success) vm.success = payload.success;

                    vm.record = { ...vm.defaultFileRecord };
                    vm.editMode = false;
                    vm.load(true);
                    vm.emitEvent('filesUpdated');
                })
                .catch((err) => {
                    console.error('Files store failed:', err);
                    this.loading = false;
                });
        },

        showConfirmDeletion(index) { this.deleteIndex = index; },

        deleteRecord(id) {
            if (this.loading) return;

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

            const vm = this;

            this.$http.post(this.routes['admin-patient-files-delete'], { id })
                .then((response) => {
                    let payload = response.data;
                    if (typeof payload === 'string') { try { payload = JSON.parse(payload); } catch { payload = {}; } }

                    if (payload.errors) {
                        vm.errors = payload.errors;
                        vm.loading = false;
                        return;
                    }
                    if (payload.success) vm.success = payload.success;

                    vm.showConfirmDeletion(-1);
                    vm.load(true);
                    vm.emitEvent('filesUpdated');
                })
                .catch((err) => {
                    console.error('Files delete failed:', err);
                    this.loading = false;
                });
        },

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

        bindImageModal() {
            this.$nextTick(function () {
                $('.bpTrackImage').mtcOverlay();
            });
        },

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

        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 sel  = Array.isArray(this.filter?.types) ? this.filter.types : [];

            if (sel.length === 0) {
                this.filteredRecords = list;
                return;
            }

            const out = [];
            for (let i = 0; i < list.length; i++) {
                if (sel.includes(list[i].type)) out.push(list[i]);
            }
            this.filteredRecords = out;
            this.filterApplied = true;
        },

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