import {defineStore} from 'pinia'
import {config} from '@/config'
import logger from "@/logger.js"
import performRequest from '@/backend.js'

export const usePremiseSingleEditStore = defineStore('premiseSingleEdit', {
    state() {
        return {
            premise: null,
            loading: false,
            calculating: false,
            routing: false,
            throwsException: true,
        }

    },
    getters: {
        showProcessingModal(state) {
            return state.calculating || state.routing;
        },
        showLoadingSpinner(state) {
            return state.loading;
        },
        isEmpty(state) {
            return state.premise === null;
        },

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

        getDestinations(state) {
            return state.premise?.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;
                }

                const d = state.premise.destinations.find(d => String(d.id) === String(id));
                if ((d ?? null) !== null) return d;
            }
        }
    },
    actions: {
        async load(id) {
            this.loading = true;
            this.premise = null;

            logger.info("load premise", id);

            const params = new URLSearchParams();
            params.append('premissIds', id.toString());
            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.premise] = data;

            this.loading = false;
        },
        async startCalculation() {

            this.calculating = true;
            const body = [this.premise?.id];
            const url = `${config.backendUrl}/calculation/start/`;
            let error = null;

            await performRequest(this, 'PUT', url, body, false, ['Premiss validation error']).catch(e => {
                error = e.errorObj;
            })

            this.calculating = false;
            return error;
        },

        /**
         * Destination editing
         */

        async addDestination(node) {

            if (this.premise === null) return;
            this.routing = true;

            const destinationNodeIds = {};
            destinationNodeIds[this.premise.id] = [node.id, ...this.premise.destinations.map(d => d.destination_node.id)];

            const body = {destination_node_ids: destinationNodeIds};
            const url = `${config.backendUrl}/calculation/destination/`;

            logger.info("addDestination", body, url);

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

            const ids = []

            if (destinations[this.premise.id]?.length !== 0)
                for (const destId of Object.keys(destinations[this.premise.id])) {
                    this.premise.destinations.push(destinations[this.premise.id][destId]);
                    ids.push(destinations[this.premise.id][destId].id);
                }

            this.routing = false;

            return ids;

        },
        async deleteDestination(id) {

            if (this.premise === null || !this.premise.destinations.some(d => String(d.id) === String(id))) return;


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

            const toBeDeleted = this.premise.destinations.findIndex(d => String(d.id) === String(id));

            if (toBeDeleted !== -1) {
                this.premise.destinations.splice(toBeDeleted, 1);
            }
        },
        async updateDestination(id) {
            if (this.premise === null) return;

            const toUpdate = this.premise.destinations.find(to => String(id) === String(to.id));

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

            logger.info(body)

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


        /**
         * Save
         */

        async savePrice() {
            let success = true;

            if (!this.premise) return;

            const body = {
                premise_ids: [this.premise.id],
                material_cost: this.premise.material_cost,
                oversea_share: this.premise.oversea_share,
                is_fca_enabled: this.premise.is_fca_enabled
            };

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

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

            if (!this.premise) return;

            const body = {
                premise_ids: [this.premise.id],

                handling_unit: {
                    weight: this.premise.handling_unit.weight,
                    weight_unit: this.premise.handling_unit.weight_unit,

                    length: this.premise.handling_unit.length,
                    width: this.premise.handling_unit.width,
                    height: this.premise.handling_unit.height,
                    dimension_unit: this.premise.handling_unit.dimension_unit,

                    content_unit_count: this.premise.handling_unit.content_unit_count,
                },

                is_mixable: this.premise.is_mixable,
                is_stackable: this.premise.is_stackable

            };

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

            return success;

        },
        async saveMaterial() {
            let success = true;


            if (!this.premise) return;

            const body = {
                premise_ids: [this.premise.id],
                hs_code: this.premise.hs_code,
                tariff_rate: this.premise.tariff_rate,

            };

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


            return success;

        },
    }
});