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

export const useDestinationEditStore = defineStore('destinationEdit', {
    state: () => ({
        destinations: null,
        loading: false,
        initialized: false,
        handlingCostMatrix: null,
        quantityMatrix: null,
        routeMatrix: null
    }),
    getters: {
        checkDestinationAssignment(state) {
            return (ids) => {
                let some = false;
                let all = true;

                ids.forEach(id => {
                    const dest = state.destinations?.get(id);

                    if ((dest ?? null) === null || dest.length === 0)
                        all = false;
                    else
                        some = true;

                });

                if (all)
                    return "all";
                else if (some)
                    return "some";
                else
                    return "none";
            }
        },
        getByPremiseId(state) {
            return (id) => {
                return state.destinations?.get(id);
            }
        },
        getByPremiseIds(state) {
            return (ids) => {
                return new Map(
                    [...state.destinations].filter(([premiseId, destinations]) => ids.includes(premiseId))
                );
            }
        },
        showProcessingModal(state) {
            return state.loading;
        },
        getHandlingCostMatrix(state) {
            return state.handlingCostMatrix;
        },
        getQuantityMatrix(state) {
            return state.quantityMatrix;
        },
        getRouteMatrix(state) {
            return state.routeMatrix;
        }
    },
    actions: {
        setHandlingCostMatrix(handlingCostMatrix) {
            this.handlingCostMatrix = handlingCostMatrix;
        },
        setQuantityMatrix(quantityMatrix) {
            this.quantityMatrix = quantityMatrix;
        },
        setRouteMatrix(routeMatrix) {
            this.routeMatrix = routeMatrix;
        },
        setupDestinations(premisses) {
            this.loading = true;

            const temp = new Map();
            premisses.forEach(p => temp.set(p.id, p.destinations));
            this.destinations = temp;

            this.initialized = true;
            this.loading = false;
        },
        async massSetDestinations(updateMatrix) {
            this.loading = true;

            const toBeAdded = {};
            const toBeDeletedMap = new Map();

            updateMatrix.forEach(row => {
                toBeAdded[row.id] = row.destinations.filter(d => d.selected).map(d => d.id);
                toBeDeletedMap.set(row.id, row.destinations.filter(d => !d.selected).map(d => d.id));
            });

            const url = `${config.backendUrl}/calculation/destination`;
            const {
                data: data,
                headers: headers
            } = await performRequest(this, 'POST', url, {'destination_node_ids': toBeAdded});

            this.destinations.forEach((destinations, premiseId) => {
                const toBeDeleted = toBeDeletedMap.get(premiseId);

                const filtered = destinations !== null ? destinations.filter(d => !toBeDeleted?.includes(d.destination_node.id)) : [];

                this.destinations.set(premiseId, [...filtered, ...data[premiseId]]);
            });


            this.loading = false;
        },
        async massUpdateDestinations(premiseIds) {
            this.loading = true;


            await new Promise(resolve => setTimeout(() => {
                this.updateQuantity();
                resolve();
            }, 10));

            await new Promise(resolve => setTimeout(() => {
                this.updateHandlingCosts();
                resolve();
            }, 10));

            await new Promise(resolve => setTimeout(() => {
                this.updateRoutes();
                resolve();
            }, 10));

            const destinationMap = new Map();

            premiseIds.forEach(premiseId => {
               this.destinations.get(premiseId)?.forEach(toUpdate => {

                   destinationMap.set(toUpdate.id,{
                       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,
                   })
               } )
            });

            await performRequest(this, 'PUT', `${config.backendUrl}/calculation/destination/all`, {destinations: Object.fromEntries(destinationMap)}, false);

            this.loading = false;
        },
        updateRoutes() {
            this.routeMatrix.forEach(row => {

                row.ids.forEach(premiseId => {
                    row.destinations.forEach(destinationUpdateInfo => {
                        const destOfCurPremisses = this.destinations.get(premiseId);

                        if ((destOfCurPremisses ?? null) !== null) {
                            const destOfCurPremise = destOfCurPremisses.find(d => destinationUpdateInfo.destinationNodeId === d.destination_node.id);

                            if(destinationUpdateInfo.ids.includes(destOfCurPremise.id)) {
                                /* set d2d stuff */
                                destOfCurPremise.is_d2d = destinationUpdateInfo.isD2d;
                                destOfCurPremise.rate_d2d = destinationUpdateInfo.rateD2d;
                                destOfCurPremise.lead_time_d2d = destinationUpdateInfo.leadTimeD2d;

                                /* set selected route */
                                const selectedRoute = destinationUpdateInfo.routes?.find(r => r.routeCompareString === destinationUpdateInfo.selectedRoute);

                                destOfCurPremise.routes.forEach(r => r.is_selected = false);

                                if(selectedRoute) {
                                    const routeOfCurPremise = destOfCurPremise.routes.find(r => selectedRoute.ids.includes(r.id));

                                    if(routeOfCurPremise) {
                                        routeOfCurPremise.is_selected = true;
                                    }
                                }
                            }
                        }
                    });
                });
            });
        },
        updateHandlingCosts() {
            this.handlingCostMatrix.forEach(row => {
                const destinations = this.destinations.get(row.id);

                if ((destinations ?? null) !== null) {

                    const destination = destinations.find(dest => dest.id === row.destinationId);

                    if ((destination ?? null) !== null) {
                        destination.disposal_costs = row.disposal_costs;
                        destination.repackaging_costs = row.repackaging_costs;
                        destination.handling_costs = row.handling_costs;
                    }
                }
            });

        },
        updateQuantity() {
            this.quantityMatrix.forEach(row => {
                const destinations = this.destinations.get(row.id);


                if ((destinations ?? null) !== null) {
                    row.destinations
                        .filter(newDest => newDest.id !== null)
                        .forEach(newDest => {

                            const found = destinations.find(dest => dest.id === newDest.id);
                            if (found)
                                found.annual_amount = newDest.annual_amount;

                        });
                }

            });
        }

    }
});