import { useEffect, useState } from "react";
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
import InputToggle from "../../../ui/inputs/InputToggle";

import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
import { useSceneContext } from "../../../../modules/scene/sceneContext";
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
import { useParams } from "react-router-dom";
import { getUserData } from "../../../../functions/getUserData";
import { useSocketStore } from "../../../../store/builder/store";
import { materials } from "./FloorProperties";

import { upsertFloorApi } from "../../../../services/factoryBuilder/floor/upsertFloorApi";

const SelectedFloorProperties = () => {
    const [depth, setDepth] = useState("");
    const [isBeveled, setIsBeveled] = useState(false);
    const [bevelStrength, setBevelStrength] = useState("");
    const { selectedFloor } = useBuilderStore();
    const { floorStore } = useSceneContext();
    const { selectedVersionStore } = useVersionContext();
    const { selectedVersion } = selectedVersionStore();
    const { socket } = useSocketStore();
    const { userId, organization } = getUserData();
    const { projectId } = useParams();
    const { getFloorById, updateFloor } = floorStore();

    const [activeSurface, setActiveSurface] = useState<"top" | "side">("top");

    const floor = selectedFloor ? getFloorById(selectedFloor.userData.floorUuid) : null;

    useEffect(() => {
        if (floor) {
            setDepth(floor.floorDepth.toString());
            setIsBeveled(floor.isBeveled);
            setBevelStrength(floor.bevelStrength.toString());
        }
    }, [floor]);

    const handleDepthChange = (val: string) => {
        setDepth(val);
        const parsed = parseFloat(val);
        if (!isNaN(parsed) && floor) {
            const updatedFloor = updateFloor(floor.floorUuid, { floorDepth: parsed });
            if (projectId) {
                if (!socket?.connected) {

                    // API

                    upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
                } else {

                    // SOCKET

                    const data = {
                        floorData: updatedFloor,
                        projectId: projectId,
                        versionId: selectedVersion?.versionId || '',
                        userId: userId,
                        organization: organization
                    }

                    socket.emit('v1:model-Floor:add', data);
                }
            }
        }
    };

    const handleBevelChange = (val: string) => {
        setBevelStrength(val);
        const parsed = parseFloat(val);
        if (!isNaN(parsed) && floor) {
            const updatedFloor = updateFloor(floor.floorUuid, { bevelStrength: parsed });
            if (projectId) {
                if (!socket?.connected) {

                    // API

                    upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
                } else {

                    // SOCKET

                    const data = {
                        floorData: updatedFloor,
                        projectId: projectId,
                        versionId: selectedVersion?.versionId || '',
                        userId: userId,
                        organization: organization
                    }

                    socket.emit('v1:model-Floor:add', data);
                }
            }
        }
    };

    const handleIsBeveledToggle = () => {
        setIsBeveled(!isBeveled);
        if (!floor) return;
        const updatedFloor = updateFloor(floor.floorUuid, { isBeveled: !floor.isBeveled });
        if (projectId) {
            if (!socket?.connected) {

                // API

                upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
            } else {

                // SOCKET

                const data = {
                    floorData: updatedFloor,
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || '',
                    userId: userId,
                    organization: organization
                }

                socket.emit('v1:model-Floor:add', data);
            }
        }

    };

    const handleSelectMaterial = (material: { textureId: string; textureName: string }) => {
        if (!floor) return;
        const key = activeSurface === "top" ? "topMaterial" : "sideMaterial";
        const updatedFloor = updateFloor(floor.floorUuid, { [key]: material.textureId });
        if (projectId) {
            if (!socket?.connected) {

                // API

                upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
            } else {

                // SOCKET

                const data = {
                    floorData: updatedFloor,
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || '',
                    userId: userId,
                    organization: organization
                }

                socket.emit('v1:model-Floor:add', data);
            }
        }

    };

    if (!floor) return null;

    const selectedMaterials = {
        top: materials.find((m) => m.textureId === floor.topMaterial) ?? materials[0],
        side: materials.find((m) => m.textureId === floor.sideMaterial) ?? materials[0],
    };

    return (
        <div className="wall-properties-container">
            <section className="wall-properties-section">
                <div className="header">Floor</div>
                <div className="wall-properties">
                    <InputWithDropDown
                        label="Depth"
                        value={depth}
                        min={0.1}
                        max={10}
                        step={0.1}
                        onChange={handleDepthChange}
                    />
                    <InputToggle
                        label="Beveled"
                        inputKey="isBeveled"
                        value={isBeveled}
                        onClick={handleIsBeveledToggle}
                    />
                    <InputWithDropDown
                        label="Bevel Strength"
                        value={bevelStrength}
                        min={1}
                        max={10}
                        step={1}
                        onChange={handleBevelChange}
                    />
                </div>
            </section>

            <section>
                <div className="header-wrapper">
                    <div className="header">Materials</div>
                </div>

                <div className="material-preview">
                    <div className="sides-wrapper">
                        {(["top", "side"] as const).map((surface) => (
                            <button
                                key={surface}
                                className={`side-wrapper ${activeSurface === surface ? "active" : ""}`}
                                onClick={() => setActiveSurface(surface)}
                            >
                                <div className="label">{surface === "top" ? "Top" : "Side"}</div>
                                <div className="texture-image">
                                    <img
                                        draggable={false}
                                        src={selectedMaterials[surface].texture}
                                        alt={selectedMaterials[surface].textureName}
                                    />
                                </div>
                            </button>
                        ))}
                    </div>

                    <div className="preview">
                        <img
                            draggable={false}
                            src={selectedMaterials[activeSurface].texture}
                            alt={selectedMaterials[activeSurface].textureName}
                        />
                    </div>
                </div>

                <div className="materials">
                    <div className="material-container">
                        {materials.map((material, index) => {
                            const isSelected = selectedMaterials[activeSurface].textureId === material.textureId;
                            return (
                                <button
                                    className={`material-wrapper ${isSelected ? "selectedMaterial" : ""}`}
                                    key={`${material.textureName}_${index}`}
                                    onClick={() => handleSelectMaterial(material)}
                                >
                                    <div className="material-property">
                                        <div className="material-image">
                                            <img
                                                draggable={false}
                                                src={material.texture}
                                                alt={material.textureName}
                                            />
                                        </div>
                                        <div className="material-name">{material.textureName}</div>
                                    </div>
                                </button>
                            );
                        })}
                    </div>
                </div>
            </section>
        </div>
    );
};

export default SelectedFloorProperties;
