import { useMemo } from 'react';
import { Shape, Vector2, DoubleSide, TextureLoader, RepeatWrapping, SRGBColorSpace } from 'three';
import { useLoader } from '@react-three/fiber';
import { Extrude } from '@react-three/drei';
import useModuleStore from '../../../../../store/useModuleStore';
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
import { useToggleView } from '../../../../../store/builder/store';
import * as Constants from '../../../../../types/world/worldConstants';

import texturePath from "../../../../../assets/textures/floor/white.png";
import texturePathDark from "../../../../../assets/textures/floor/black.png";
import material1 from '../../../../../assets/textures/floor/factory wall texture.jpg';

function FloorInstance({ floor }: { floor: Floor }) {
    const { togglView } = useToggleView();
    const { activeModule } = useModuleStore();
    const { selectedFloor, setSelectedFloor, setSelectedDecal } = useBuilderStore();
    const savedTheme = localStorage.getItem('theme');

    const materials: Record<string, string> = {
        "Default Material": savedTheme === "dark" ? texturePathDark : texturePath,
        "Material 1": savedTheme === "dark" ? material1 : material1,
    };

    const shape = useMemo(() => {
        const shape = new Shape();
        const points = floor.points.map(p => new Vector2(p.position[0], p.position[2]));
        if (points.length < 3) return null;
        shape.moveTo(points[0].x, points[0].y);
        for (let i = 1; i < points.length; i++) {
            shape.lineTo(points[i].x, points[i].y);
        }
        return shape;
    }, [floor]);

    const textureScale = Constants.floorConfig.textureScale;

    const [topTexture, sideTexture] = useLoader(
        TextureLoader,
        [
            materials[floor.topMaterial] || materials['Default Material'],
            materials[floor.sideMaterial] || materials['Default Material']
        ]
    );

    if (!materials[floor.topMaterial] || !materials[floor.sideMaterial]) return null;

    [topTexture, sideTexture].forEach(tex => {
        tex.wrapS = tex.wrapT = RepeatWrapping;
        tex.repeat.set(textureScale, textureScale);
        tex.colorSpace = SRGBColorSpace;
    });

    if (!shape) return null;

    return (
        <mesh
            castShadow
            receiveShadow
            name={`Floor-${floor.floorUuid}`}
            rotation={[Math.PI / 2, 0, 0]}
            position={[0, !floor.isBeveled ? (floor.floorDepth - 0.1) : (floor.floorDepth - 0.2), 0]}
            userData={floor}
            onDoubleClick={(e) => {
                if (!togglView && activeModule === 'builder') {
                    if (e.object.userData.floorUuid) {
                        e.stopPropagation();
                        setSelectedFloor(e.object);
                        setSelectedDecal(null);
                    }
                }
            }}
            onPointerMissed={() => {
                if (selectedFloor && selectedFloor.userData.floorUuid === floor.floorUuid) {
                    setSelectedFloor(null);
                }
            }}
        >
            <Extrude
                name={`Floor-${floor.floorUuid}`}
                args={[shape, {
                    depth: !floor.isBeveled ? floor.floorDepth : (floor.floorDepth - 0.1),
                    bevelEnabled: floor.isBeveled,
                    bevelSegments: floor.bevelStrength,
                    bevelOffset: -0.1,
                    bevelSize: 0.1,
                    bevelThickness: 0.1,
                }]}
                userData={floor}
            >
                <meshStandardMaterial
                    attach="material-0"
                    color={Constants.floorConfig.defaultColor}
                    map={topTexture}
                    side={DoubleSide}
                />
                <meshStandardMaterial
                    attach="material-1"
                    color={Constants.floorConfig.defaultColor}
                    map={sideTexture}
                    side={DoubleSide}
                />
            </Extrude>
        </mesh>
    );
}

export default FloorInstance;