import { useEffect, useMemo, useState } from "react";
import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger";
import StorageAction from "../actions/StorageAction";
import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useSelectedAction, useSelectedEventData } from "../../../../../../store/simulation/useSimulationStore";
import * as THREE from 'three';
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";

function StorageMechanics() {
    const [activeOption, setActiveOption] = useState<"default" | "store" | "spawn">("default");
    const [selectedPointData, setSelectedPointData] = useState<StoragePointSchema | undefined>();
    const { selectedEventData } = useSelectedEventData();
    const { productStore } = useSceneContext();
    const { getPointByUuid, updateAction } = productStore();
    const { selectedProductStore } = useProductContext();
    const { selectedProduct } = selectedProductStore();
    const { setSelectedAction, clearSelectedAction } = useSelectedAction();
    const { selectedVersionStore } = useVersionContext();
    const { selectedVersion } = selectedVersionStore();
    const { projectId } = useParams();

    const updateSelectedPointData = () => {
        if (selectedEventData && selectedProduct) {
            const point = getPointByUuid(
                selectedProduct.productUuid,
                selectedEventData?.data.modelUuid,
                selectedEventData?.selectedPoint
            ) as StoragePointSchema | undefined;
            if (point && "action" in point) {
                setSelectedPointData(point);
                const uiOption = point.action.actionType === "retrieve" ? "spawn" : point.action.actionType;
                setActiveOption(uiOption as "store" | "spawn");
                setSelectedAction(point.action.actionUuid, point.action.actionName);
            }
        }
    };

    useEffect(() => {
        if (selectedEventData) {
            const point = getPointByUuid(
                selectedProduct.productUuid,
                selectedEventData?.data.modelUuid,
                selectedEventData?.selectedPoint
            ) as StoragePointSchema | undefined;
            if (point && "action" in point) {
                setSelectedPointData(point);
                const uiOption = point.action.actionType === "retrieve" ? "spawn" : point.action.actionType;
                setActiveOption(uiOption as "store" | "spawn");
                setSelectedAction(point.action.actionUuid, point.action.actionName);
            }
        } else {
            clearSelectedAction();
        }
    }, [selectedProduct, selectedEventData]);

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

    const handleActionTypeChange = (option: string) => {
        if (!selectedEventData || !selectedPointData) return;
        const internalOption = actionTypeMap[option as keyof typeof actionTypeMap] as "store" | "retrieve";

        setActiveOption(option as "store" | "spawn");

        const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, {
            actionType: internalOption,
        });

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

    const handleRenameAction = (newName: string) => {
        if (!selectedPointData) return;
        const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { actionName: newName });

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

    const handleCapacityChange = (value: string) => {
        if (!selectedEventData || !selectedPointData) return;
        const newCapacity = parseInt(value);

        const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, {
            storageCapacity: newCapacity,
        });

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

    const createNewMaterial = (materialType: string): { materialType: string; materialId: string } | null => {
        if (!selectedEventData || !selectedPointData) return null;
        const materialId = THREE.MathUtils.generateUUID();
        return {
            materialType,
            materialId
        };
    };

    const handleMaterialTypeChange = (value: string) => {
        if (!selectedEventData || !selectedPointData) return;

        const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, {
            materialType: value,
        });

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

    const currentActionName = useMemo(() =>
        selectedPointData ? selectedPointData.action.actionName : "Action Name",
        [selectedPointData]
    );

    const currentCapacity = useMemo(() =>
        selectedPointData ? selectedPointData.action.storageCapacity.toString() : "0",
        [selectedPointData]
    );

    const currentMaterialType = useMemo(() =>
        selectedPointData?.action.materialType || "Default material",
        [selectedPointData]
    );

    const availableActions = {
        defaultOption: "store",
        options: ["store", "spawn"],
    };

    const actionTypeMap = {
        spawn: "retrieve",
        store: "store"
    };

    return (
        <>
            {selectedEventData && (
                <section>
                    <ActionsList
                        selectedPointData={selectedPointData}
                    />
                    <div className="selected-actions-details">
                        <div className="selected-actions-header">
                            <RenameInput
                                value={currentActionName}
                                canEdit={false}
                            />
                        </div>
                        <div className="selected-actions-list">
                            <LabledDropdown
                                defaultOption={activeOption}
                                options={availableActions.options}
                                onSelect={handleActionTypeChange}
                            />
                            <StorageAction
                                type={activeOption}
                                value={currentCapacity}
                                defaultValue="0"
                                min={0}
                                currentMaterialType={currentMaterialType}
                                handleCapacityChange={handleCapacityChange}
                                handleMaterialTypeChange={handleMaterialTypeChange}
                            />
                        </div>
                    </div>
                    <div className="tirgger">
                        <Trigger selectedPointData={selectedPointData as any} type={'StorageUnit'} />
                    </div>
                </section>
            )}
        </>
    );
}

export default StorageMechanics;