import {createSlice, PayloadAction} from "@reduxjs/toolkit";
import {Order, OrderProduct} from "../../types/order";
import {Assembly, ASSEMBLY_STATE} from "../../types/assembly";
import selectProductElement from "../../components/Modals/SelectProductModal/SelectProductElement";


export interface AssemblyState {
    order?: Order;
    initialOrder?: Order;
    assembly?: Assembly;
    selectedProductId?: number;
    localState?: ASSEMBLY_STATE;
    selectedProduct?: OrderProduct
}

const initialState: AssemblyState = {
    localState: ASSEMBLY_STATE.NOT_STARTED
}

export const assembly = createSlice({
    name: 'assembly',
    initialState,
    reducers: {
        setOrder: (state, action) => {
            state.initialOrder = action.payload;
            state.order = action.payload;
            state.selectedProductId = 0;
            state.localState = ASSEMBLY_STATE.NOT_STARTED;
        },
        setAssembly: (state, action: PayloadAction<Assembly>) => {
            state.assembly = action.payload;
            state.localState = action.payload.state;
        },
        startAssembly: (state) => {
            if (!state.assembly) return;
            state.assembly.createdAt = (new Date()).toDateString();

            state.assembly.state = ASSEMBLY_STATE.ASSEMBLING_PRODUCTS;
            state.localState = ASSEMBLY_STATE.ASSEMBLING_PRODUCTS;
        },
        endAssembly: (state) => {
            if (!state.assembly) return;
            state.assembly.endedAt = (new Date()).toDateString();

            state.assembly.state = ASSEMBLY_STATE.ENDED;
            state.localState = ASSEMBLY_STATE.ENDED;

            state.assembly = undefined;
            state.localState = ASSEMBLY_STATE.NOT_STARTED;
            state.order = undefined;
        },
        confirmAssembly: (state) => {
            if (!state.assembly) return;
            state.assembly.state = ASSEMBLY_STATE.CONFIRMED;
            state.localState = ASSEMBLY_STATE.CONFIRMED;
        },
        setAssembled: (state, action: PayloadAction<{ orderProductId: number }>) => {
            if (!state.order || !state.order.products || !state.assembly) return;
            const orderProductId = action.payload.orderProductId;
            state.order.products.forEach(product => {
                if (product.databaseId === orderProductId) {
                    product.assembled = true;
                }
            });
            state.selectedProduct = state.order.products.find(product => product.databaseId == action.payload.orderProductId);
            // If all products is assembled
            if (!state.order.products.find(product => !product.assembled)) {
                state.assembly.state = ASSEMBLY_STATE.ALL_PRODUCTS_ASSEMBLED;
                state.localState = ASSEMBLY_STATE.ALL_PRODUCTS_ASSEMBLED;
            }
        },
        setShipped: (state, action: PayloadAction<{ orderProductId: number }>) => {
            if (!state.order || !state.order.products) return;

            const orderProductId = action.payload.orderProductId;

            state.order.products.forEach(product => {
                if (product.databaseId === orderProductId) {
                    product.shipped = true;
                }
            });
            state.selectedProduct = state.order.products.find(product => product.databaseId == action.payload.orderProductId);
        },
        setLocalState: (state, action: PayloadAction<ASSEMBLY_STATE>) => {
            state.localState = action.payload;
        },
        selectProduct: (state, action: PayloadAction<number>) => {
            if (!state.order) return;
            state.selectedProduct = state.order.products[action.payload];
        },
        reset: (state) => {
            state.assembly = undefined;
            state.order = undefined;
            state.localState = ASSEMBLY_STATE.NOT_STARTED
            state.selectedProductId = undefined;
            state.selectedProduct = undefined;
        }
    }
})

export const {
    setOrder,
    setAssembled,
    selectProduct,
    setAssembly,
    startAssembly,
    endAssembly,
    confirmAssembly,
    setLocalState,
    reset
} = assembly.actions;
export default assembly.reducer;