import { TransformControls } from "@react-three/drei";
import * as THREE from "three";
import { useSelectedFloorItem, useObjectPosition, useObjectRotation, useActiveTool, useSocketStore } from "../../../../store/builder/store";
import { useThree } from "@react-three/fiber";

import { useEffect, useRef, useState } from "react";
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
// import { setAssetsApi } from "../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi";
import { useParams } from "react-router-dom";
import { useProductContext } from "../../../simulation/products/productContext";
import { getUserData } from "../../../../functions/getUserData";
import { useSceneContext } from "../../sceneContext";
import { useVersionContext } from "../../../builder/version/versionContext";

export default function TransformControl() {
    const state = useThree();
    const ref = useRef(null);
    const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
    const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
    const { setObjectPosition } = useObjectPosition();
    const { setObjectRotation } = useObjectRotation();
    const { activeTool } = useActiveTool();
    const { socket } = useSocketStore();
    const { selectedProductStore } = useProductContext();
    const { selectedProduct } = selectedProductStore();
    const { assetStore, eventStore, productStore, undoRedo3DStore } = useSceneContext();
    const { push3D } = undoRedo3DStore();
    const { updateAsset, getAssetById } = assetStore();
    const { userId, organization } = getUserData();
    const { selectedVersionStore } = useVersionContext();
    const { selectedVersion } = selectedVersionStore();
    const { projectId } = useParams();

    const updateBackend = (
        productName: string,
        productUuid: string,
        projectId: string,
        eventData: EventsSchema
    ) => {
        upsertProductOrEventApi({
            productName: productName,
            productUuid: productUuid,
            projectId: projectId,
            eventDatas: eventData,
            versionId: selectedVersion?.versionId || '',
        });
    };

    function handleObjectChange() {
        if (selectedFloorItem) {
            setObjectPosition(selectedFloorItem.position);
            setObjectRotation({
                x: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.x),
                y: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.y),
                z: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.z),
            });
        }
    }

    function handleMouseUp() {
        if (selectedFloorItem) {
            setObjectPosition(selectedFloorItem.position);
            setObjectRotation({
                x: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.x),
                y: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.y),
                z: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.z),
            });
        }
        const asset = getAssetById(selectedFloorItem?.uuid);
        if (asset) {
            if (asset.eventData) {
                const eventData = eventStore.getState().getEventByModelUuid(asset.modelUuid);
                const productData = productStore.getState().getEventByModelUuid(selectedProduct.productUuid, asset.modelUuid);

                if (eventData) {
                    eventStore.getState().updateEvent(asset.modelUuid, {
                        position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z] as [number, number, number],
                        rotation: [selectedFloorItem.rotation.x, selectedFloorItem.rotation.y, selectedFloorItem.rotation.z] as [number, number, number],
                    });
                }

                if (productData) {
                    const event = productStore
                        .getState()
                        .updateEvent(
                            selectedProduct.productUuid,
                            asset.modelUuid,
                            {
                                position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z] as [number, number, number],
                                rotation: [selectedFloorItem.rotation.x, selectedFloorItem.rotation.y, selectedFloorItem.rotation.z] as [number, number, number],
                            }
                        );

                    if (event) {
                        updateBackend(
                            selectedProduct.productName,
                            selectedProduct.productUuid,
                            projectId || '',
                            event
                        );
                    }
                }
            }

            updateAsset(asset.modelUuid, {
                position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z],
                rotation: [selectedFloorItem.rotation.x, selectedFloorItem.rotation.y, selectedFloorItem.rotation.z] as [number, number, number],
            });

            //REST

            // await setAssetsApi(
            //     organization,
            //     asset.modelUuid,
            //     asset.modelName,
            //     [selectedFloorItem.position.x, 0, selectedFloorItem.position.z,
            //     { "x": selectedFloorItem.rotation.x, "y": selectedFloorItem.rotation.y, "z": selectedFloorItem.rotation.z },
            //     asset.assetId,
            //     false,
            //     true,
            // );

            //SOCKET

            const data = {
                organization,
                modelUuid: asset.modelUuid,
                modelName: asset.modelName,
                assetId: asset.assetId,
                position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z] as [number, number, number],
                rotation: { x: selectedFloorItem.rotation.x, y: selectedFloorItem.rotation.y, z: selectedFloorItem.rotation.z },
                isLocked: false,
                isVisible: true,
                socketId: socket.id,
                versionId: selectedVersion?.versionId || '',
                userId,
                projectId
            };

            socket.emit("v1:model-asset:add", data);

            push3D({
                type: 'Scene',
                actions: [
                    {
                        module: "builder",
                        actionType: "Asset-Update",
                        asset: {
                            type: "Asset",
                            assetData: asset,
                            newData: {
                                ...asset,
                                position: [selectedFloorItem.position.x, 0, selectedFloorItem.position.z],
                                rotation: [selectedFloorItem.rotation.x, selectedFloorItem.rotation.y, selectedFloorItem.rotation.z],
                            },
                            timeStap: new Date().toISOString()
                        }
                    }
                ]
            });
        }
    }

    useEffect(() => {
        const handleKeyDown = (e: KeyboardEvent) => {
            const isTextInput = (element: Element | null): boolean =>
                element instanceof HTMLInputElement ||
                element instanceof HTMLTextAreaElement ||
                element?.getAttribute("contenteditable") === "true";
            if (isTextInput(document.activeElement)) return;
            const keyCombination = detectModifierKeys(e);
            if (!selectedFloorItem) return;
            if (keyCombination === "G") {
                setTransformMode((prev) => (prev === "translate" ? null : "translate"));
            }
            if (keyCombination === "R") {
                setTransformMode((prev) => (prev === "rotate" ? null : "rotate"));
            }
        };

        if (selectedFloorItem) {
            window.addEventListener("keydown", handleKeyDown);
            setObjectPosition(selectedFloorItem.position);
            setObjectRotation({
                x: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.x),
                y: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.y),
                z: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.z),
            });
        } else {
            setTransformMode(null);
        }

        return () => {
            window.removeEventListener("keydown", handleKeyDown);
        };
    }, [selectedFloorItem]);

    useEffect(() => {
        if (activeTool === "delete") {
            if (state.controls) {
                const target = (state.controls as any).getTarget(new THREE.Vector3());
                (state.controls as any).setTarget(target.x, 0, target.z, true);
            }
            setSelectedFloorItem(null);
            setObjectPosition({ x: undefined, y: undefined, z: undefined });
            setObjectRotation({ x: undefined, y: undefined, z: undefined });
        }
    }, [activeTool]);

    return (
        <>
            {(selectedFloorItem && transformMode) &&
                <TransformControls
                    ref={ref}
                    showX={transformMode === "translate"}
                    showY={transformMode === "rotate" || transformMode === "translate"}
                    showZ={transformMode === "translate"}
                    object={selectedFloorItem}
                    mode={transformMode}
                    onObjectChange={handleObjectChange}
                    onMouseUp={handleMouseUp}
                />
            }
        </>
    );
}
