import { Object3D } from 'three';
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';

interface BuilderState {
    // Point & Line Interaction
    hoveredPoint: Point | null;
    snappedPoint: Point | null;
    snappedPosition: [number, number, number] | null;
    hoveredLine: [Point, Point] | null;

    // Wall Settings
    selectedWall: Object3D | null;
    wallThickness: number;
    wallHeight: number;
    outsideMaterial: string;
    insideMaterial: string;

    // Decal Settings
    selectedDecal: Object3D | null;

    // Aisle General
    selectedAisle: Object3D | null;
    aisleType: AisleTypes;
    aisleWidth: number;
    aisleColor: AisleColors;

    // Aisle Specific Styles
    dashLength: number;
    gapLength: number;
    dotRadius: number;
    aisleLength: number;
    isFlipped: boolean;

    // Setters - Point/Line
    setHoveredPoint: (point: Point | null) => void;
    setSnappedPoint: (point: Point | null) => void;
    setSnappedPosition: (position: [number, number, number] | null) => void;
    setHoveredLine: (line: [Point, Point] | null) => void;

    // Setters - Wall
    setSelectedWall: (wall: Object3D | null) => void;
    setWallThickness: (thickness: number) => void;
    setWallHeight: (height: number) => void;
    setWallMaterial: (material: string, side: 'inside' | 'outside') => void;

    // Setters - Decal
    setSelectedDecal: (decal: Object3D | null) => void;

    // Setters - Aisle General
    setSelectedAisle: (aisle: Object3D | null) => void;
    setAisleType: (type: AisleTypes) => void;
    setAisleWidth: (width: number) => void;
    setAisleColor: (color: AisleColors) => void;

    // Setters - Aisle Specific
    setDashLength: (length: number) => void;
    setGapLength: (length: number) => void;
    setDotRadius: (radius: number) => void;
    setAisleLength: (length: number) => void;
    setIsFlipped: (isFlipped: boolean) => void;

    // Batch Setters
    setDashedAisleProperties: (width: number, dashLength: number, gapLength: number) => void;
    setDottedAisleProperties: (width: number, dotRadius: number, gapLength: number) => void;
    setArrowsAisleProperties: (width: number, aisleLength: number, gapLength: number) => void;
    setAisleProperties: (type: AisleTypes, width: number, color: AisleColors) => void;
}

export const useBuilderStore = create<BuilderState>()(
    immer((set) => ({
        // === Defaults ===
        hoveredPoint: null,
        snappedPoint: null,
        snappedPosition: null,
        hoveredLine: null,

        selectedWall: null,
        wallThickness: 0.5,
        wallHeight: 7,
        outsideMaterial: 'Default Material',
        insideMaterial: 'Material 1',

        selectedDecal: null,

        selectedAisle: null,
        aisleType: 'solid-aisle',
        aisleWidth: 0.1,
        aisleColor: 'yellow',

        dashLength: 0.5,
        gapLength: 0.3,
        dotRadius: 0.1,
        aisleLength: 0.6,
        isFlipped: false,

        // === Setters: Point/Line ===

        setHoveredPoint: (point: Point | null) => {
            set((state) => {
                state.hoveredPoint = point;
            });
        },

        setSnappedPoint: (point: Point | null) => {
            set((state) => {
                state.snappedPoint = point;
            });
        },

        setSnappedPosition: (position: [number, number, number] | null) => {
            set((state) => {
                state.snappedPosition = position;
            });
        },

        setHoveredLine: (line: [Point, Point] | null) => {
            set((state) => {
                state.hoveredLine = line;
            })
        },

        // === Setters: Wall ===

        setSelectedWall: (wall: Object3D | null) => {
            set((state) => {
                state.selectedWall = wall;
            })
        },

        setWallThickness: (thickness: number) => {
            set((state) => {
                state.wallThickness = thickness;
            })
        },

        setWallHeight: (height: number) => {
            set((state) => {
                state.wallHeight = height;
            })
        },

        setWallMaterial: (material: string, side: 'inside' | 'outside') => {
            set((state) => {
                if (side === 'outside') state.outsideMaterial = material;
                else state.insideMaterial = material;
            });
        },

        // === Setters: Decal ===

        setSelectedDecal: (decal: Object3D | null) => {
            set((state) => {
                state.selectedDecal = decal;
            })
        },

        // === Setters: Aisle General ===

        setSelectedAisle: (aisle: Object3D | null) => {
            set((state) => {
                state.selectedAisle = aisle;
            });
        },

        setAisleType: (type) => {
            set((state) => {
                state.aisleType = type;
            });
        },

        setAisleWidth: (width) => {
            set((state) => {
                state.aisleWidth = width;
            });
        },

        setAisleColor: (color) => {
            set((state) => {
                state.aisleColor = color;
            });
        },

        // === Setters: Aisle Specific ===

        setDashLength: (length) => {
            set((state) => {
                state.dashLength = length;
            });
        },

        setGapLength: (length) => {
            set((state) => {
                state.gapLength = length;
            });
        },

        setDotRadius: (radius) => {
            set((state) => {
                state.dotRadius = radius;
            });
        },

        setAisleLength: (length) => {
            set((state) => {
                state.aisleLength = length;
            });
        },

        setIsFlipped: (isFlipped) => {
            set((state) => {
                state.isFlipped = isFlipped;
            });
        },

        // === Batch Setters ===

        setDashedAisleProperties: (width, dashLength, gapLength) => set((state) => {
            state.aisleType = 'dashed-aisle';
            state.aisleWidth = width;
            state.dashLength = dashLength;
            state.gapLength = gapLength;
        }),

        setDottedAisleProperties: (width, dotRadius, gapLength) => set((state) => {
            state.aisleType = 'dotted-aisle';
            state.aisleWidth = width;
            state.dotRadius = dotRadius;
            state.gapLength = gapLength;
        }),

        setArrowsAisleProperties: (width, aisleLength, gapLength) => set((state) => {
            state.aisleType = 'arrows-aisle';
            state.aisleWidth = width;
            state.aisleLength = aisleLength;
            state.gapLength = gapLength;
        }),

        setAisleProperties: (type, width, color) => set((state) => {
            state.aisleType = type;
            state.aisleWidth = width;
            state.aisleColor = color;
        })
    }))
);
