import * as THREE from "three";
import { MeshProps } from "@react-three/fiber";
import { useRef } from "react";
import { useToolMode } from "../../../../../../store/builder/store";
import { useDeletableEventSphere, useSelectedEventSphere } from "../../../../../../store/simulation/useSimulationStore";
import { useSceneContext } from "../../../../../scene/sceneContext";
import { useProductContext } from "../../../../products/productContext";
import { useVersionContext } from "../../../../../builder/version/versionContext";
import { useParams } from "react-router-dom";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";

interface PointInstanceProps extends Omit<MeshProps, 'ref'> {
    point: {
        uuid: string;
        position: [number, number, number];
    };
    modelUuid: string;
    color: string;
}

export default function PointInstance({
    point,
    modelUuid,
    color,
    ...meshProps
}: PointInstanceProps) {
    const ref = useRef<THREE.Mesh>(null);
    const { setSelectedEventSphere } = useSelectedEventSphere();
    const { deletableEventSphere, setDeletableEventSphere, clearDeletableEventSphere } = useDeletableEventSphere();
    const { toolMode } = useToolMode();
    const { productStore } = useSceneContext();
    const { getEventByModelUuid, getTriggersByTriggeredPointUuid, removeTrigger, removePoint } = productStore();
    const { selectedProductStore } = useProductContext();
    const { selectedProduct } = selectedProductStore();
    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 || '',
        })
    }

    const handleEventPointDelete = () => {
        const eventModel = getEventByModelUuid(selectedProduct.productUuid, modelUuid);
        if (!eventModel || eventModel.type !== 'transfer' || eventModel.points.length < 2) return;

        const triggers = getTriggersByTriggeredPointUuid(selectedProduct.productUuid, point.uuid);

        const updatedEvents: EventsSchema[] = [];
        if (triggers.length > 0) {
            triggers.map((trigger) => {
                const event = removeTrigger(selectedProduct.productUuid, trigger.triggerUuid);
                if (event) {
                    updatedEvents.push(event);
                }
            })
        }

        const event = removePoint(selectedProduct.productUuid, modelUuid, point.uuid)

        if (event) {
            updatedEvents.push(event);
        }

        if (updatedEvents.length > 0) {
            updatedEvents.map((updatedEvent) => {
                updateBackend(
                    selectedProduct.productName,
                    selectedProduct.productUuid,
                    projectId || '',
                    updatedEvent
                );
            })
        }
    }

    return (
        <mesh
            {...meshProps}
            ref={ref}
            name="Event-Sphere"
            uuid={point.uuid}
            position={new THREE.Vector3(...point.position)}
            onClick={(e) => {
                e.stopPropagation();
                if (toolMode === 'cursor') {
                    setSelectedEventSphere(ref.current);
                } else if (toolMode === '3D-Delete') {
                    handleEventPointDelete()
                }
            }}
            onPointerOver={(e) => {
                e.stopPropagation();
                if (toolMode === '3D-Delete' && (!deletableEventSphere || deletableEventSphere.uuid !== point.uuid)) {
                    setDeletableEventSphere(ref.current);
                }
            }}
            onPointerOut={(e) => {
                e.stopPropagation();
                if (toolMode === '3D-Delete' && deletableEventSphere && deletableEventSphere.uuid === point.uuid) {
                    clearDeletableEventSphere();
                }
            }}
            userData={{ modelUuid, pointUuid: point.uuid }}
        >
            <sphereGeometry args={[0.1, 16, 16]} />
            <meshStandardMaterial color={color} />
        </mesh>
    );
}
