import {defineStore} from 'pinia'
import {config} from '@/config'
import {toRaw} from "vue";
import {useErrorStore} from "@/store/error.js";
import logger from "@/logger.js"
import performRequest from '@/backend.js'

export const usePremiseEditStore = defineStore('premiseEdit', {
        state() {
            return {
                premisses: null,

                /**
                 *  set to true while the store is loading the premises.
                 */
                loading: false,

                /**
                 * set to true while the store sets the selected/deselected field in the premises.
                 */
                selectedLoading: false,


                destinations: null,
                processDestinationMassEdit: false,

                selectedDestination: null,

                throwsException: true,

            }
        },
        getters: {

            getCountryIdByPremiseIds(state) {
                return function (ids) {
                    if (state.loading) {
                        if (state.throwsException)
                            throw new Error("Premises are accessed while still loading.");
                        return null;
                    }

                    const premiss = state.premisses?.filter(p => ids.some(id => id === p.id));

                    const premiseCountryMap = new Map();
                    premiss?.forEach(premise => {
                        premiseCountryMap.set(premise.id, premise.supplier?.country?.id);
                    });

                    return premiseCountryMap;

                }


            },

            /**
             * Returns the ids of all premises.
             * @param state
             * @returns {*}
             */
            getPremiseIds(state) {
                if (state.loading) {
                    if (state.throwsException)
                        throw new Error("Premises are accessed while still loading.");

                    return null;
                }

                return state.premisses?.map(p => p.id);
            },

            /**
             * Returns the premises.
             * @param state
             * @returns {null|*[]|*}
             */
            getPremisses(state) {
                if (state.loading) {
                    if (state.throwsException)
                        throw new Error("Premises are accessed while still loading.");

                    return null;
                }

                return state.premisses;
            },

            /**
             * Returns the premise with the given id.
             * @param state
             * @returns {function(*): *}
             */
            getById(state) {
                return function (id) {
                    if (state.loading) {
                        if (state.throwsException)
                            throw new Error("Premises are accessed while still loading.");

                        return null;
                    }

                    if ((id ?? null) === null) {
                        return null;
                    }

                    return state.premisses.find(p => p.id === id);
                };
            },

            /**
             * Returns all premises that are selected.
             * @param state
             * @returns {T[]}
             */
            getSelectedPremisses(state) {
                if (state.loading || state.selectedLoading) {
                    if (state.throwsException)
                        throw new Error("Premises are accessed while still loading.");

                    return null;
                }

                return state.premisses.filter(p => p.selected);
            },


            /**
             * Returns all premise ids that are selected.
             * @param state
             * @returns {T[]}
             */
            getSelectedPremissesIds(state) {
                if (state.loading || state.selectedLoading) {
                    if (state.throwsException)
                        throw new Error("Premises are accessed while still loading.");

                    return null;
                }

                return state.premisses.filter(p => p.selected).map(p => p.id);
            },

            /**
             * Getters for controlling frontend views
             * ======================================
             */

            /**
             * Returns true if no premises are loaded. The frontend can show a message that no premises are found.
             * @param state
             * @returns {*|boolean}
             */
            showEmpty(state) {
                return (!state.loading && (((state.premisses ?? null) === null) || state.premisses.length === 0))
            },

            /**
             * Returns true if the premises are loaded and not empty. The frontend can show a the loaded premisses.
             * @param state
             * @returns {boolean}
             */
            showData(state) {
                return (!state.loading && !((state.premisses ?? null) === null) && state.premisses.length !== 0)
            },

            /**
             * Returns true if the premises are loaded and not empty. The frontend can show a the loaded premisses.
             * @param state
             * @returns {boolean}
             */
            isLoading(state) {
                return (state.loading);
            },

            showProcessingModal(state) {
                return state.processDestinationMassEdit;
            },

            /**
             * Getters for single edit view
             * ============================
             */

            /**
             * Returns true if only one premise is selected.
             * @param state
             * @returns {boolean|null}
             */
            isSingleSelect(state) {
                if (state.loading || state.selectedLoading) {
                    if (state.throwsException)
                        throw new Error("Premises are accessed while still loading.");

                    return null;
                }

                return state.premisses.filter(p => p.selected).length === 1;
            },

            /**
             * Returns the id of the single selected premise.
             * @param state
             * @returns {*}
             */
            singleSelectId(state) {
                if (state.loading || state.selectedLoading) {
                    if (state.throwsException)
                        throw new Error("Premises are accessed while still loading.");

                    return null;
                }

                if (!state.isSingleSelect) {
                    return null;
                    //     throw new Error("Single selected premise accessed, but not in single select mode");
                }


                return state.premisses.find(p => p.selected)?.id;
            },


            /**
             * Returns the single selected premise.
             * @param state
             * @returns {*}
             */
            singleSelectedPremise(state) {
                if (state.loading || state.selectedLoading) {
                    if (state.throwsException)
                        throw new Error("Premises are accessed while still loading.");

                    return null;
                }

                if (!state.isSingleSelect) {
                    return null;
                    // throw new Error("Single selected premise accessed, but not in single select mode");
                }

                return state.premisses?.find(p => p.selected);
            },

            /**
             * Getters for destination editing
             * ===============================
             */

            getDestinationsView(state) {
                return state.destinations?.destinations ?? [];
            },

            getDestinationById(state) {
                return function (id) {
                    if (state.loading || state.selectedLoading) {
                        if (state.throwsException)
                            throw new Error("Premises are accessed while still loading.");

                        return null;
                    }

                    for (const p of state.premisses) {
                        const d = p.destinations.find(d => d.id === id);
                        if ((d ?? null) !== null) return d;
                    }
                }
            },

            getSelectedDestinationsData: (state) => state.selectedDestination,


        },
        actions: {
            async batchUpdatePrice(ids, priceData) {
                const updatedPremises = this.premisses.map(p => {
                    if (ids.includes(p.id)) {
                        return {
                            ...p,
                            ...(priceData.price !== null && {material_cost: priceData.price}),
                            ...(priceData.overSeaShare !== null && {oversea_share: priceData.overSeaShare}),
                            ...(priceData.includeFcaFee !== null && {is_fca_enabled: priceData.includeFcaFee})
                        };
                    }
                    return p;
                });
                this.premisses = updatedPremises;

                return await this.savePrice(ids, priceData);
            },
            async batchUpdateMaterial(ids, materialData, tariffRates = null) {
                const updatedPremises = this.premisses.map(p => {
                    if (ids.includes(p.id)) {
                        return {
                            ...p,
                            material: {
                                ...p.material,
                            },
                            ...(materialData.hsCode !== null && {hs_code: materialData.hsCode}),
                            ...((tariffRates !== null) ? {tariff_rate: tariffRates.get(p.id)} : (materialData.tariffRate !== null && {tariff_rate: materialData.tariffRate}))
                        };
                    }
                    return p;
                });
                this.premisses = updatedPremises;



                return await this.saveMaterial(ids, materialData, tariffRates);
            },
            async batchUpdatePackaging(ids, packagingData) {


                const updatedPremises = this.premisses.map(p => {
                    if (ids.includes(p.id)) {
                        return {
                            ...p,
                            handling_unit: {
                                ...p.handling_unit,
                                ...(packagingData.weight !== null && {weight: packagingData.weight}),
                                ...(packagingData.width !== null && {width: packagingData.width}),
                                ...(packagingData.length !== null && {length: packagingData.length}),
                                ...(packagingData.height !== null && {height: packagingData.height}),
                                ...(packagingData.weightUnit !== null && {weight_unit: packagingData.weightUnit}),
                                ...(packagingData.dimensionUnit !== null && {dimension_unit: packagingData.dimensionUnit}),
                                ...(packagingData.unitCount !== null && {content_unit_count: packagingData.unitCount})
                            },
                            ...(packagingData.stackable !== null && {is_stackable: packagingData.stackable}),
                            ...(packagingData.mixable !== null && {is_mixable: packagingData.mixable})
                        };
                    }
                    return p;
                });
                this.premisses = updatedPremises;

                logger.info("packaging data:", toRaw(packagingData), "update result", toRaw(updatedPremises));

                return await this.savePackaging(ids, packagingData);
            },
            async startCalculation() {

                const body = this.premisses.map(p => p.id);
                const url = `${config.backendUrl}/calculation/start/`;
                let error = null;

                await performRequest(this, 'PUT', url, body, false, ['Premiss validation error', 'Internal Server Error']).catch(e => {
                    logger.log("startCalculation exception", e.errorObj);
                    error = e.errorObj;
                })

                return error;
            },

            /**
             * DESTINATION stuff
             * =================
             */

            prepareDestinations(dataSourcePremiseId, editedPremiseIds, massEdit = false, fromMassEditView = false) {
                if (this.premisses === null) return;
                if (!editedPremiseIds || !dataSourcePremiseId || editedPremiseIds.length === 0) return;

                this.destinations = {
                    premise_ids: editedPremiseIds,
                    massEdit: massEdit,
                    fromMassEditView: fromMassEditView,
                    destinations: this.premisses.find(p => String(p.id) === String(dataSourcePremiseId))?.destinations.map(d => this.copyAllFromPremises(d, !massEdit)) ?? [],
                };

                this.selectedDestination = null;

            },
            async executeDestinationsMassEdit() {

                if (!this.destinations.massEdit) {

                    this.destinations.premise_ids.forEach(premiseId => {
                        const toPremise = this.getById(premiseId);

                        this.destinations.destinations.forEach(fromDest => {
                            const toDest = toPremise.destinations.find(to => fromDest.id.substring(1) === String(to.id));

                            if ((toDest ?? null) === null) {
                                throw new Error("Destination not found in premise: " + premiseId + " -> " + d.id);
                            }

                            this.copyAllToPremise(fromDest, toDest);

                            const body = {
                                annual_amount: toDest.annual_amount,
                                repackaging_costs: toDest.repackaging_costs,
                                handling_costs: toDest.handling_costs,
                                disposal_costs: toDest.disposal_costs,
                                is_d2d: toDest.is_d2d,
                                rate_d2d: toDest.rate_d2d,
                                lead_time_d2d: toDest.lead_time_d2d,
                                route_selected_id: toDest.routes.find(r => r.is_selected)?.id ?? null,
                            };

                            const url = `${config.backendUrl}/calculation/destination/${toDest.id}`;
                            performRequest(this, 'PUT', url, body, false);

                        });
                    });


                } else {
                    this.processDestinationMassEdit = true;

                    const destinations = [];

                    this.destinations.destinations.forEach(d => {
                        const dest = {
                            destination_node_id: d.destination_node.id,
                            annual_amount: d.annual_amount,
                            disposal_costs: d.userDefinedHandlingCosts ? d.disposal_costs : null,
                            repackaging_costs: d.userDefinedHandlingCosts ? d.repackaging_costs : null,
                            handling_costs: d.userDefinedHandlingCosts ? d.handling_costs : null,
                        }
                        destinations.push(dest);
                    })

                    const body = {destinations: destinations, premise_id: this.destinations.premise_ids};
                    const url = `${config.backendUrl}/calculation/destination/`;

                    const {data: data, headers: headers} = await performRequest(this, 'PUT', url, body).catch(e => {
                        this.destinations = null;
                        this.processDestinationMassEdit = false;
                    });

                    if (data) {
                        for (const id of Object.keys(data)) {
                            this.premisses.find(p => String(p.id) === id).destinations = data[id];
                        }
                    }

                    this.destinations = null;
                    this.processDestinationMassEdit = false;
                }
            },
            cancelMassEdit() {
                this.destinations = null;
            },

            copyAllFromPremises(from, fullCopy = true) {

                const d = {};

                d.id = `e${from.id}`;
                d.destination_node = structuredClone(toRaw(from.destination_node));
                d.routes = fullCopy ? structuredClone(toRaw(from.routes)) : null;

                d.annual_amount = from.annual_amount;
                d.is_d2d = from.is_d2d;
                d.rate_d2d = from.is_d2d ? from.rate_d2d : null;
                d.lead_time_d2d = from.is_d2d ? from.lead_time_d2d : null;
                d.handling_costs = from.handling_costs;
                d.disposal_costs = from.disposal_costs;
                d.repackaging_costs = from.repackaging_costs;
                d.userDefinedHandlingCosts = from.handling_costs !== null || from.disposal_costs !== null || from.repackaging_costs !== null;

                return d;
            },
            copyAllToPremise(from, to, fullCopy = true) {

                const d = to ?? {};

                d.annual_amount = from.annual_amount;
                d.is_d2d = from.is_d2d;
                d.rate_d2d = from.is_d2d ? from.rate_d2d : null;
                d.lead_time_d2d = from.is_d2d ? from.lead_time_d2d : null;

                if (from.userDefinedHandlingCosts) {
                    d.disposal_costs = from.disposal_costs;
                    d.repackaging_costs = from.repackaging_costs;
                    d.handling_costs = from.handling_costs;
                } else {
                    d.disposal_costs = null;
                    d.repackaging_costs = null;
                    d.handling_costs = null;
                }

                if (fullCopy && (from.routes ?? null) !== null) {
                    to.routes.forEach(route => route.is_selected = from.routes.find(r => r.id === route.id)?.is_selected ?? false);
                }

                return d;
            },

            /**
             * Selects all destinations for the given "ids" for editing.
             * This creates a copy of the destination with id "id".
             * They are written back as soon as the user closes the dialog.
             */
            selectDestination(id) {
                if (this.premisses === null) return;

                logger.info("selectDestination:", id)

                const dest = this.destinations.destinations.find(d => d.id === id);


                if ((dest ?? null) == null) {
                    const error = {
                        code: 'Frontend error.',
                        message: `Destination not found: ${id}. Please contact support.`,
                        trace: null
                    }
                    throw new Error("Internal frontend error: Destination not found: " + id);
                }

                this.selectedDestination = structuredClone(toRaw(dest));
            },
            async deselectDestinations(save = false) {
                if (this.premisses === null) return;


                if (save) {
                    const idx = this.destinations.destinations.findIndex(d => d.id === this.selectedDestination.id);
                    this.destinations.destinations.splice(idx, 1, this.selectedDestination);

                    if (!this.destinations.fromMassEditView) {
                        //TODO write trough backend if no massEdit

                        const toDest = this.singleSelectedPremise.destinations.find(to => this.selectedDestination.id.substring(1) === String(to.id));
                        this.copyAllToPremise(this.selectedDestination, toDest);

                        const body = {
                            annual_amount: toDest.annual_amount,
                            repackaging_costs: toDest.repackaging_costs,
                            handling_costs: toDest.handling_costs,
                            disposal_costs: toDest.disposal_costs,
                            is_d2d: toDest.is_d2d,
                            rate_d2d: toDest.rate_d2d,
                            lead_time_d2d: toDest.lead_time_d2d,
                            route_selected_id: toDest.routes.find(r => r.is_selected)?.id ?? null,
                        };

                        logger.info(body)

                        const url = `${config.backendUrl}/calculation/destination/${toDest.id}`;
                        await performRequest(this, 'PUT', url, body, false);

                    }

                }

                this.selectedDestination = null;
            },
            async deleteDestination(id) {


                /*
                 * 1. delete from destinations copy
                 */
                const idx = this.destinations.destinations.findIndex(d => d.id === id);

                if (idx === -1) {
                    logger.info("Destination not found in mass edit: , id)");
                    return;
                }

                this.destinations.destinations.splice(idx, 1);

                /*
                 * 2. delete from backend if not mass edit
                 */

                if (!this.destinations.massEdit && id.startsWith('e')) { /* 'v'-ids cannot be deleted because they only exist in the frontend */
                    if (this.premisses === null) return;

                    const origId = id.substring(1);

                    const url = `${config.backendUrl}/calculation/destination/${origId}`;
                    await performRequest(this, 'DELETE', url, null, false).catch(async e => {
                        logger.error("Unable to delete destination: " + origId + "");
                        logger.error(e);
                        await this.loadPremissesIfNeeded(this.premisses.map(p => p.id));
                    });

                    for (const p of this.premisses) {
                        const toBeDeleted = p.destinations.findIndex(d => String(d.id) === String(origId))

                        logger.info(toBeDeleted)

                        if (toBeDeleted !== -1) {
                            p.destinations.splice(toBeDeleted, 1)
                            break;
                        }
                    }
                }
            },
            async addDestination(node) {

                if (this.destinations.massEdit) {

                    const existing = this.destinations.destinations.find(d => d.destination_node.id === node.id);
                    logger.info(existing)

                    if ((existing ?? null) !== null) {
                        logger.info("Destination already exists", node.id);
                        return [existing.id];
                    }

                    const destination = {
                        id: `v${node.id}`,
                        destination_node: structuredClone(toRaw(node)),
                        massEdit: true,
                        annual_amount: 0,
                        is_d2d: false,
                        rate_d2d: null,
                        lead_time_d2d: null,
                        disposal_costs: null,
                        repackaging_costs: null,
                        handling_costs: null,
                        userDefinedHandlingCosts: false,
                    };

                    this.destinations.destinations.push(destination);

                    return [destination.id];

                } else {
                    const id = node.id;

                    this.processDestinationMassEdit = true;


                    const toBeUpdated = this.destinations.fromMassEditView ? this.destinations.premise_ids : this.premisses?.filter(p => p.selected).map(p => p.id);

                    if (toBeUpdated === null || toBeUpdated.length === 0) return;

                    const body = {destination_node_id: id, premise_id: toBeUpdated};
                    const url = `${config.backendUrl}/calculation/destination/`;


                    const {data: destinations} = await performRequest(this, 'POST', url, body).catch(e => {
                        this.loading = false;
                        this.selectedLoading = false;
                        this.processDestinationMassEdit = false;
                        throw e;
                    });

                    const mappedIds = []

                    for (const id of Object.keys(destinations)) {
                        const premise = this.premisses.find(p => String(p.id) === id)
                        premise.destinations.push(destinations[id]);
                        const mappedDestination = this.copyAllFromPremises(destinations[id], true);
                        mappedIds.push(mappedDestination.id);
                        this.destinations.destinations.push(mappedDestination);
                    }

                    this.processDestinationMassEdit = false;

                    return mappedIds;
                }
            },


            /**
             * Set methods
             * (these are more extensive changes. The edited premises are replaced by the one returned by the backend)
             */

            async setSupplier(id, updateMasterData, ids = null) {
                logger.info("setSupplier");

                const selectedId = this.singleSelectId;

                this.processDestinationMassEdit = true;

                const body = {supplier_node_id: id, update_master_data: updateMasterData};
                const url = `${config.backendUrl}/calculation/supplier/`;
                await this.setData(url, body, ids);

                if (selectedId != null && this.destinations && !this.destinations.fromMassEditView) {
                    this.prepareDestinations(selectedId, [selectedId]);
                }

                this.processDestinationMassEdit = false;

            },
            async setMaterial(id, updateMasterData, ids = null) {
                logger.info("setMaterial");
                const body = {material_id: id, update_master_data: updateMasterData};
                const url = `${config.backendUrl}/calculation/material/`;
                await this.setData(url, body, ids);
            },
            async setData(url, body, ids = null) {

                const toBeUpdated = this.premisses ? (ids ? (ids) : (this.premisses.filter(p => p.selected).map(p => p.id))) : null;

                if (null !== toBeUpdated) {
                    this.selectedLoading = true;
                    this.loading = true;

                    body.premise_id = toBeUpdated;
                    logger.info(url, body)

                    const {data: data} = await performRequest(this, 'PUT', url, body).catch(e => {
                        this.loading = false;
                    });

                    if (data) {
                        data.forEach(p => p.selected = true);
                        this.premisses = this.replacePremissesById(this.premisses, data);
                    }

                    this.loading = false;
                    this.selectedLoading = false;
                }
            },

            /**
             * Replace the premisses with the loaded ones by id.
             * This is used to update the premisses after a "Set" change.
             * @param premisses
             * @param loadedData
             * @returns {*}
             */
            replacePremissesById(premisses, loadedData) {
                const replacementMap = new Map(loadedData.map(obj => [obj.id, obj]));
                const replaced = premisses.map(obj => replacementMap.get(obj.id) || obj);
                logger.info("Replaced", replaced);
                return replaced;
            },

            /**
             * Save
             */

            async savePrice(ids = null, priceData = null) {
                let success = true;
                const toBeUpdated = this.premisses ? (ids ? (ids.map(id => this.premisses.find(p => String(p.id) === String(id)))) : (this.premisses.filter(p => p.selected))) : null;

                if (!toBeUpdated?.length) return;

                const body = {
                    premise_ids: toBeUpdated.map(p => p.id),
                    material_cost: priceData === null ? toBeUpdated[0].material_cost : priceData.price,
                    oversea_share: priceData === null ? toBeUpdated[0].oversea_share : priceData.overSeaShare,
                    is_fca_enabled: priceData === null ? toBeUpdated[0].is_fca_enabled : priceData.includeFcaFee
                };

                await performRequest(this, 'POST', `${config.backendUrl}/calculation/price/`, body, false).catch(e => {
                    success = false;
                })

                return success;
            },
            async savePackaging(ids = null, packagingData = null) {
                let success = true;

                const toBeUpdated = this.premisses ? (ids ? (ids.map(id => this.premisses.find(p => String(p.id) === String(id)))) : (this.premisses.filter(p => p.selected))) : null;

                if (!toBeUpdated?.length) return;

                const body = {
                    premise_ids: toBeUpdated.map(p => p.id),

                    handling_unit: {
                        weight: packagingData === null ? toBeUpdated[0].handling_unit.weight : packagingData.weight,
                        weight_unit: packagingData === null ? toBeUpdated[0].handling_unit.weight_unit : packagingData.weightUnit,

                        length: packagingData === null ? toBeUpdated[0].handling_unit.length : packagingData.length,
                        width: packagingData === null ? toBeUpdated[0].handling_unit.width : packagingData.width,
                        height: packagingData === null ? toBeUpdated[0].handling_unit.height : packagingData.height,
                        dimension_unit: packagingData === null ? toBeUpdated[0].handling_unit.dimension_unit : packagingData.dimensionUnit,

                        content_unit_count: packagingData === null ? toBeUpdated[0].handling_unit.content_unit_count : packagingData.unitCount,
                    },

                    is_mixable: packagingData === null ? toBeUpdated[0].is_mixable : packagingData.mixable,
                    is_stackable: packagingData === null ? toBeUpdated[0].is_stackable : packagingData.stackable,

                };

                await performRequest(this, 'POST', `${config.backendUrl}/calculation/packaging/`, body, false).catch(() => {
                    success = false;
                })

                return success;

            },
            async saveMaterial(ids = null, materialData = null, tariffRates = null) {
                let success = true;
                const toBeUpdated = this.premisses ? (ids ? (ids.map(id => this.premisses.find(p => String(p.id) === String(id)))) : (this.premisses.filter(p => p.selected))) : null;


                if (!toBeUpdated?.length) return;

                const body = {
                    premise_ids: toBeUpdated.map(p => p.id),

                    hs_code: materialData === null ? toBeUpdated[0].hs_code : materialData.hsCode,
                    tariff_rate: (null !== tariffRates) ? null : materialData === null ? toBeUpdated[0].tariff_rate : materialData.tariffRate,
                    tariff_rates: (null === tariffRates) ? null : Object.fromEntries(tariffRates),
                };

                await performRequest(this, 'POST', `${config.backendUrl}/calculation/material/`, body, false).catch(() => {
                    success = false;
                })


                return success;

            },

            /**
             * PREMISE stuff
             * =================
             */
            deselectPremise() {
                this.selectedLoading = true;

                this.premisses.forEach(p => p.selected = false);

                this.destinations = null;
                this.selectedDestination = null;
                this.selectedLoading = false;
            },
            setAll(value) {

                this.selectedLoading = true;

                const updatedPremises = this.premisses.map(p => ({
                    ...p,
                    selected: value
                }));
                this.premisses = updatedPremises;

                this.selectedLoading = false;

            },
            setSelectTo(ids, value) {
                this.selectedLoading = true;

                const idsSet = new Set(ids);
                const updatedPremises = this.premisses.map(p => ({
                    ...p,
                    selected: idsSet.has(p.id) ? value : p.selected
                }));
                this.premisses = updatedPremises;

                this.selectedLoading = false;
            },
            async selectSinglePremise(id, ids) {
                this.selectedLoading = true;

                await this.loadPremissesIfNeeded(ids);

                this.premisses.forEach(p => p.selected = String(id) === String(p.id));

                this.prepareDestinations(id, [id]);

                this.selectedLoading = false;
            },
            async loadAndSelectSinglePremise(id) {

                this.loading = true;
                this.selectedLoading = true;
                this.premises = [];

                const params = new URLSearchParams();
                params.append('premissIds', `${[id]}`);
                const url = `${config.backendUrl}/calculation/edit/${params.size === 0 ? '' : '?'}${params.toString()}`;

                const {data: data, headers: headers} = await performRequest(this, 'GET', url, null).catch(e => {
                    this.selectedLoading = false;
                    this.loading = false;
                });
                this.premisses = data;

                this.premisses.forEach(p => p.selected = true);
                this.prepareDestinations(id, [id]);
                this.selectedLoading = false;
                this.loading = false;
            },
            async loadPremissesIfNeeded(ids, exact = false) {
                const reload = this.premisses ? !ids.every((id) => this.premisses.find(d => d.id === id) && (!exact || ids.length === this.premisses.length)) : true;

                if (reload) {
                    await this.loadPremissesForced(ids);
                }
            },
            async loadPremissesForced(ids) {

                this.loading = true;
                this.premises = [];

                const params = new URLSearchParams();
                params.append('premissIds', ids.join(', '));
                const url = `${config.backendUrl}/calculation/edit/${params.size === 0 ? '' : '?'}${params.toString()}`;

                const {data: data, headers: headers} = await performRequest(this, 'GET', url, null).catch(e => {
                    this.loading = false;
                });
                this.premisses = data;

                this.premisses.forEach(p => p.selected = false);
                this.loading = false;


            },
            removePremise(id) {
                const idx = this.premisses.findIndex(p => p.id === id);
                this.premisses.splice(idx, 1);
            }
        }
    })
;