import {defineStore} from 'pinia'
import {config} from '@/config'
import {useErrorStore} from "@/store/error.js";
import {useStageStore} from "@/store/stage.js";
import {usePropertySetsStore} from "@/store/propertySets.js";
import logger from "@/logger.js";

export const useReportSearchStore = defineStore('reportSearch', {
    state() {
        return {
            suppliers: [],
            selectedIds: [],
            remainingSuppliers: [],
            material: null,
            loading: false,
        }
    },
    getters: {
        getSuppliers(state) {
            return state.remainingSuppliers;
        },
        isSelected(state) {
            return function (id) {
                return state.selectedIds.includes(id);
            }
        },
        getSelectedIds(state) {
            return state.selectedIds;
        },
        getMaterialId(state) {
            return state.material?.id;
        },
        getMaterial(state) {
            return state.material;
        },
    },
    actions: {
        async selectSupplier(id) {

            if (!this.selectedIds.includes(id))
                this.selectedIds.push(id)
            else {
                const index = this.selectedIds.findIndex(selectedId => selectedId === id);
                this.selectedIds.splice(index, 1);
            }


            this.updateShownSuppliers();
        },
        updateShownSuppliers() {
            const toBeShown = []

            this.suppliers.forEach(supplierList => {
                const shouldInclude = this.selectedIds.every(id => supplierList.some(s => s.id === id))

                if (shouldInclude)
                    toBeShown.push(...supplierList);
            })


            this.remainingSuppliers = toBeShown.filter((item, index) =>
                toBeShown.findIndex(obj => obj.id === item.id) === index
            );
        },
        async setMaterial(material) {
            this.material = material;
            await this.updateSuppliers();
        },
        async updateSuppliers() {
            if (this.getMaterialId == null) return;

            this.loading = true;
            this.suppliers = [];
            this.selectedIds = [];
            this.remainingSuppliers = [];

            const params = new URLSearchParams();
            params.append('material', this.getMaterialId);
            const url = `${config.backendUrl}/reports/search/${params.size === 0 ? '' : '?'}${params.toString()}`;

            this.suppliers = await this.performRequest('GET', url, null).catch(e => {
                this.loading = false;
            });

            this.updateShownSuppliers();

            this.loading = false;
        },
        async performRequest(method, url, body, expectResponse = true) {

            const params = {
                method: method,
                headers: {
                    'Content-Type': 'application/json'
                }
            };

            if (body) {
                params.body = JSON.stringify(body);
            }

            const request = {url: url, params: params};
            logger.info("Request:", request);

            const response = await fetch(url, params
            ).catch(e => {
                const error = {
                    code: 'Network error.',
                    message: "Please check your internet connection.",
                    trace: null
                }

                logger.error(error);
                const errorStore = useErrorStore();
                void errorStore.addError(error, {store: this, request: request});

                throw e;
            });

            let data = null;
            if (expectResponse) {
                data = await response.json().catch(e => {
                    const error = {
                        code: 'Malformed response',
                        message: "Malformed server response. Please contact support.",
                        trace: null
                    }

                    logger.error(error);
                    const errorStore = useErrorStore();
                    void errorStore.addError(error, {store: this, request: request});
                    throw e;
                });

                if (!response.ok) {
                    const error = {
                        code: data.error.code,
                        title: data.error.title,
                        message: data.error.message,
                        trace: data.error.trace
                    }

                    logger.error(error);
                    const errorStore = useErrorStore();
                    void errorStore.addError(error, {store: this, request: request});
                    throw new Error('Internal backend error');
                }
            } else {
                if (!response.ok) {

                    const data = await response.json().catch(e => {
                        const error = {
                            code: "Return code error " + response.status,
                            message: "Server returned wrong response code",
                            trace: null
                        }
                        logger.error(error);
                        const errorStore = useErrorStore();
                        void errorStore.addError(error, {store: this, request: request});
                        throw new Error('Internal backend error');

                    });

                    const error = {
                        code: data.error.code,
                        title: data.error.title,
                        message: data.error.message,
                        trace: data.error.trace
                    }

                    logger.error(error);
                    const errorStore = useErrorStore();
                    void errorStore.addError(error, {store: this, request: request});
                    throw new Error('Internal backend error');


                }
            }

            logger.info("Response:", data);
            return data;
        }
    },

});