import { create } from "zustand";
import { immer } from "zustand/middleware/immer";

interface CraneStore {
    cranes: CraneStatus[];

    addCrane: (productUuid: string, event: CraneEventSchema) => void;
    removeCrane: (modelUuid: string) => void;
    updateCrane: (
        modelUuid: string,
        updates: Partial<Omit<CraneStatus, "modelUuid" | "productUuid">>
    ) => void;
    clearCranes: () => void;

    setCurrentPhase: (modelUuid: string, phase: string) => void;

    addCurrentAction: (modelUuid: string, actionUuid: string, materialType: string | null, materialId: string | null) => void;
    removeCurrentAction: (modelUuid: string) => void;

    setCraneActive: (modelUuid: string, isActive: boolean) => void;
    setCraneScheduled: (modelUuid: string, isScheduled: boolean) => void;
    setIsCaryying: (modelUuid: string, isCarrying: boolean) => void;
    setCraneLoad: (modelUuid: string, load: number) => void;
    setCraneState: (modelUuid: string, newState: CraneStatus["state"]) => void;
    incrementCraneLoad: (modelUuid: string, incrementBy: number) => void;
    decrementCraneLoad: (modelUuid: string, decrementBy: number) => void;

    addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void;
    setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string }[]) => void;
    removeLastMaterial: (modelUuid: string) => { materialType: string; materialId: string } | undefined;
    getLastMaterial: (modelUuid: string) => { materialType: string; materialId: string } | undefined;
    clearCurrentMaterials: (modelUuid: string) => void;

    incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
    incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
    resetTime: (modelUuid: string) => void;

    getCraneById: (modelUuid: string) => CraneStatus | undefined;
    getCranesByProduct: (productUuid: string) => CraneStatus[];
    getActiveCranes: () => CraneStatus[];
}

export const createCraneStore = () => {
    return create<CraneStore>()(
        immer((set, get) => ({
            cranes: [],

            addCrane: (productUuid, event) => {
                set((state) => {
                    const exists = state.cranes.some(c => c.modelUuid === event.modelUuid);
                    if (!exists) {
                        state.cranes.push({
                            ...event,
                            productUuid,
                            currentPhase: 'init',
                            isActive: false,
                            isScheduled: false,
                            isCarrying: false,
                            idleTime: 0,
                            activeTime: 0,
                            currentLoad: 0,
                            currentMaterials: []
                        });
                    }
                });
            },

            removeCrane: (modelUuid) => {
                set((state) => {
                    state.cranes = state.cranes.filter(c => c.modelUuid !== modelUuid);
                });
            },

            updateCrane: (modelUuid, updates) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        Object.assign(crane, updates);
                    }
                });
            },

            clearCranes: () => {
                set((state) => {
                    state.cranes = [];
                });
            },

            setCurrentPhase: (modelUuid, phase) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.currentPhase = phase;
                    }
                });
            },

            addCurrentAction: (modelUuid, actionUuid, materialType, materialId) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        const action = crane.point.actions.find(a => a.actionUuid === actionUuid);
                        if (action) {
                            crane.currentAction = {
                                actionUuid: action.actionUuid,
                                actionName: action.actionName,
                                materialType: materialType,
                                materialId: materialId
                            };
                        }
                    }
                });
            },

            removeCurrentAction: (modelUuid) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.currentAction = undefined;
                    }
                });
            },

            setCraneActive: (modelUuid, isActive) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.isActive = isActive;
                    }
                });
            },

            setCraneScheduled: (modelUuid, isScheduled) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.isScheduled = isScheduled;
                    }
                });
            },

            setIsCaryying: (modelUuid, isCarrying) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.isCarrying = isCarrying;
                    }
                });
            },

            setCraneLoad: (modelUuid, load) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.currentLoad = load;
                    }
                });
            },

            setCraneState: (modelUuid, newState) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.state = newState;
                    }
                });
            },

            incrementCraneLoad: (modelUuid, incrementBy) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.currentLoad += incrementBy;
                    }
                });
            },

            decrementCraneLoad: (modelUuid, decrementBy) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.currentLoad = Math.max(0, crane.currentLoad - decrementBy);
                    }
                });
            },

            addCurrentMaterial: (modelUuid, materialType, materialId) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.currentMaterials.push({ materialType, materialId });
                    }
                });
            },

            setCurrentMaterials: (modelUuid, materials) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.currentMaterials = materials;
                    }
                });
            },

            removeLastMaterial: (modelUuid) => {
                let removed;
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane && crane.currentMaterials.length > 0) {
                        removed = JSON.parse(JSON.stringify(crane.currentMaterials.pop()));
                    }
                });
                return removed;
            },

            getLastMaterial: (modelUuid) => {
                const crane = get().cranes.find(c => c.modelUuid === modelUuid);
                if (crane && crane.currentMaterials.length > 0) {
                    return crane.currentMaterials[crane.currentMaterials.length - 1];
                }
                return undefined;
            },

            clearCurrentMaterials: (modelUuid) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.currentMaterials = [];
                    }
                });
            },

            incrementActiveTime: (modelUuid, incrementBy) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.activeTime += incrementBy;
                    }
                });
            },

            incrementIdleTime: (modelUuid, incrementBy) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.idleTime += incrementBy;
                    }
                });
            },

            resetTime: (modelUuid) => {
                set((state) => {
                    const crane = state.cranes.find(c => c.modelUuid === modelUuid);
                    if (crane) {
                        crane.activeTime = 0;
                        crane.idleTime = 0;
                    }
                });
            },

            getCraneById: (modelUuid) => {
                return get().cranes.find(c => c.modelUuid === modelUuid);
            },

            getCranesByProduct: (productUuid) => {
                return get().cranes.filter(c => c.productUuid === productUuid);
            },

            getActiveCranes: () => {
                return get().cranes.filter(c => c.isActive);
            }
        }))
    );
};

export type CraneStoreType = ReturnType<typeof createCraneStore>;