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 Asset
    selectedWallAsset: Object3D | null;
    deletableWallAsset: Object3D | null;

    // Floor Asset
    selectedFloorAsset: Object3D | null;
    loopAnimation: boolean;

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

    // Floor Settings
    selectedFloor: Object3D | null;
    floorDepth: number;
    isBeveled: boolean;
    bevelStrength: number;
    sideMaterial: string;
    topMaterial: string;

    // Zone Settings
    selectedZone: Object3D | null;
    zoneHeight: number;
    zoneColor: 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 Asset
    setSelectedWallAsset: (asset: Object3D | null) => void;
    setDeletableWallAsset: (asset: Object3D | null) => void;

    // Setters - Floor Asset
    setSelectedFloorAsset: (asset: Object3D | null) => void;
    setLoopAnimation: (loop: boolean) => void;

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

    // Setters - Floor
    setSelectedFloor: (floor: Object3D | null) => void;
    setFloorDepth: (depth: number) => void;
    setIsBeveled: (isBeveled: boolean) => void;
    setBevelStrength: (strength: number) => void;
    setFloorMaterial: (material: string, side: 'side' | 'top') => void;

    // Setters - Zone
    setSelectedZone: (zone: Object3D | null) => void;
    setZoneHeight: (height: number) => void;
    setZoneColor: (color: string) => 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,

        selectedWallAsset: null,
        deletableWallAsset: null,

        selectedFloorAsset: null,
        loopAnimation: true,

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

        selectedFloor: null,
        floorDepth: 0.1,
        isBeveled: false,
        bevelStrength: 5,
        sideMaterial: 'Material 1',
        topMaterial: 'Default Material',

        selectedZone: null,
        zoneHeight: 7,
        zoneColor: 'blue',

        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 Asset ===

        setSelectedWallAsset(asset: Object3D | null) {
            set((state) => {
                state.selectedWallAsset = asset;
            });
        },

        setDeletableWallAsset(asset: Object3D | null) {
            set((state) => {
                state.deletableWallAsset = asset;
            });
        },

        // === Setters: Floor Asset ===

        setSelectedFloorAsset(asset: Object3D | null) {
            set((state) => {
                state.selectedFloorAsset = asset;
            });
        },

        setLoopAnimation(loopAnimation: boolean) {
            set((state) => {
                state.loopAnimation = loopAnimation;
            });
        },

        // === 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: Floor ===
        setSelectedFloor: (floor: Object3D | null) => {
            set((state) => {
                state.selectedFloor = floor;
            });
        },

        setFloorDepth: (depth: number) => {
            set((state) => {
                state.floorDepth = depth;
            });
        },

        setIsBeveled: (isBeveled: boolean) => {
            set((state) => {
                state.isBeveled = isBeveled;
            });
        },

        setBevelStrength: (strength: number) => {
            set((state) => {
                state.bevelStrength = strength;
            });
        },

        setFloorMaterial: (material: string, side: 'side' | 'top') => {
            set((state) => {
                if (side === 'side') state.sideMaterial = material;
                else state.topMaterial = material;
            });
        },

        // === Setters: Zone ===

        setSelectedZone: (zone: Object3D | null) => {
            set((state) => {
                state.selectedZone = zone;
            });
        },

        setZoneHeight: (height: number) => {
            set((state) => {
                state.zoneHeight = height;
            });
        },

        setZoneColor: (color: string) => {
            set((state) => {
                state.zoneColor = color;
            });
        },

        // === 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;
        })
    }))
);
