import { useEffect, useState } from "react";
import { MathUtils } from "three";
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger";
import ActionsList from "../components/ActionsList";
import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
import { useParams } from "react-router-dom";
import WorkerAction from "../actions/workerAction";
import AssemblyAction from "../actions/assemblyAction";

function HumanMechanics() {
    const [activeOption, setActiveOption] = useState<"worker" | "assembly">("worker");
    const [speed, setSpeed] = useState("0.5");
    const [loadCapacity, setLoadCapacity] = useState("1");
    const [processTime, setProcessTime] = useState(10);
    const [swappedMaterial, setSwappedMaterial] = useState("Default material");
    const [currentAction, setCurrentAction] = useState<HumanAction | undefined>();
    const [selectedPointData, setSelectedPointData] = useState<HumanPointSchema | undefined>();
    const { selectedEventData } = useSelectedEventData();
    const { productStore } = useSceneContext();
    const { getPointByUuid, updateEvent, updateAction, addAction, removeAction, getEventByModelUuid } = productStore();
    const { selectedProductStore } = useProductContext();
    const { selectedProduct } = selectedProductStore();
    const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
    const { selectedVersionStore } = useVersionContext();
    const { selectedVersion } = selectedVersionStore();
    const { projectId } = useParams();

    useEffect(() => {
        if (selectedEventData && selectedEventData.data.type === "human") {
            const point = getPointByUuid(
                selectedProduct.productUuid,
                selectedEventData.data.modelUuid,
                selectedEventData.selectedPoint
            ) as HumanPointSchema | undefined;

            if (point?.action) {
                setSelectedPointData(point);
                setCurrentAction(point.action);
                setSelectedAction(point.action.actionUuid, point.action.actionName);
                setSpeed((
                    getEventByModelUuid(
                        selectedProduct.productUuid,
                        selectedEventData?.data.modelUuid || ""
                    ) as HumanEventSchema | undefined
                )?.speed?.toString() || "1");
                setLoadCapacity(point.action.loadCapacity.toString());
                setProcessTime(point.action.processTime || 10);
                setSwappedMaterial(point.action.swapMaterial || "Default material");
            }
        } else {
            clearSelectedAction();
        }
    }, [selectedEventData, selectedProduct]);

    useEffect(() => {
        if (selectedEventData && selectedProduct.productUuid) {
            const point = getPointByUuid(
                selectedProduct.productUuid,
                selectedEventData.data.modelUuid,
                selectedEventData.selectedPoint
            ) as HumanPointSchema | undefined;

            if (point?.action) {
                setSelectedPointData(point);
                setCurrentAction(point.action);
                setActiveOption(point.action.actionType);
                setSelectedAction(point.action.actionUuid, point.action.actionName);
            }
        } else {
            clearSelectedAction();
            setCurrentAction(undefined);
            setSpeed("0.5");
            setLoadCapacity("1");
        }
    }, [selectedEventData, selectedProduct, selectedAction]);

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

    const handleSelectActionType = (actionType: string) => {
        if (!selectedAction.actionId || !currentAction || !selectedPointData) return;

        const updatedAction = { ...currentAction, actionType: actionType as "worker" };
        const updatedPoint = { ...selectedPointData, action: updatedAction };

        const event = updateAction(
            selectedProduct.productUuid,
            selectedAction.actionId,
            updatedAction
        );

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

        setCurrentAction(updatedAction);
        setSelectedPointData(updatedPoint);
    };

    const handleSpeedChange = (value: string) => {
        if (!selectedEventData) return;

        const numericValue = parseFloat(value);
        if (isNaN(numericValue)) return;

        const updatedEvent = {
            ...selectedEventData.data,
            speed: numericValue
        } as HumanEventSchema;

        const event = updateEvent(
            selectedProduct.productUuid,
            selectedEventData.data.modelUuid,
            updatedEvent
        );

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

        setSpeed(value);
    };

    const handleLoadCapacityChange = (value: string) => {
        if (!currentAction || !selectedPointData || !selectedAction.actionId) return;

        const updatedAction = { ...currentAction };
        updatedAction.loadCapacity = parseInt(value)

        const updatedPoint = { ...selectedPointData, action: updatedAction };

        const event = updateAction(
            selectedProduct.productUuid,
            selectedAction.actionId,
            updatedAction
        );

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

        setCurrentAction(updatedAction);
        setSelectedPointData(updatedPoint);
        setLoadCapacity(value);
    };

    const handleProcessTimeChange = (value: number) => {
        if (!currentAction || !selectedPointData || !selectedAction.actionId) return;

        const updatedAction = { ...currentAction };
        updatedAction.processTime = value

        const updatedPoint = { ...selectedPointData, action: updatedAction };

        const event = updateAction(
            selectedProduct.productUuid,
            selectedAction.actionId,
            updatedAction
        );

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

        setCurrentAction(updatedAction);
        setSelectedPointData(updatedPoint);
        setProcessTime(value);
    };

    const handleMaterialChange = (value: string) => {
        if (!currentAction || !selectedPointData || !selectedAction.actionId) return;

        const updatedAction = { ...currentAction };
        updatedAction.swapMaterial = value

        const updatedPoint = { ...selectedPointData, action: updatedAction };

        const event = updateAction(
            selectedProduct.productUuid,
            selectedAction.actionId,
            updatedAction
        );

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

        setCurrentAction(updatedAction);
        setSelectedPointData(updatedPoint);
        setSwappedMaterial(value);
    };

    const handleClearPoints = () => {
        if (!currentAction || !selectedPointData || !selectedAction.actionId) return;

        const updatedAction = { ...currentAction };
        delete updatedAction.pickUpPoint;
        delete updatedAction.dropPoint;

        const updatedPoint = { ...selectedPointData, action: updatedAction };

        const event = updateAction(
            selectedProduct.productUuid,
            selectedAction.actionId,
            updatedAction
        );

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

        setCurrentAction(updatedAction);
        setSelectedPointData(updatedPoint);
    };

    const handleAddAction = () => {
        if (!selectedEventData || !selectedPointData) return;

        const newAction: HumanAction = {
            actionUuid: MathUtils.generateUUID(),
            actionName: `Action`,
            actionType: "worker",
            loadCapacity: 1,
            triggers: [],
        };

        const event = addAction(
            selectedProduct.productUuid,
            selectedEventData.data.modelUuid,
            selectedEventData.selectedPoint,
            newAction
        );

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

        const updatedPoint = { ...selectedPointData, action: newAction };
        setSelectedPointData(updatedPoint);
        setSelectedAction(newAction.actionUuid, newAction.actionName);
    };

    const handleDeleteAction = () => {
        if (!selectedPointData) return;

        const event = removeAction(
            selectedProduct.productUuid,
            selectedPointData.action.actionUuid
        );

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

        const updatedPoint = { ...selectedPointData, action: undefined as any };
        setSelectedPointData(updatedPoint);
        clearSelectedAction();
        setCurrentAction(undefined);
    };

    return (
        <>
            <div className="global-props section">
                <div className="property-list-container">
                    <div className="property-item">
                        <InputWithDropDown
                            label="Speed"
                            value={speed}
                            min={0}
                            step={0.1}
                            defaultValue="0.5"
                            max={10}
                            activeOption="m/s"
                            onClick={() => { }}
                            onChange={handleSpeedChange}
                        />
                    </div>
                </div>
            </div>
            <section>
                <ActionsList
                    selectedPointData={selectedPointData}
                    multipleAction={false}
                    handleAddAction={handleAddAction}
                    handleDeleteAction={handleDeleteAction}
                />

                {selectedAction.actionId && currentAction && (
                    <div className="selected-actions-details">
                        <div className="selected-actions-header">
                            <RenameInput value={selectedAction.actionName || ""} canEdit={false} />
                        </div>
                        <div className="selected-actions-list">
                            <LabledDropdown
                                label="Action Type"
                                defaultOption={activeOption}
                                options={["worker", "assembly"]}
                                onSelect={handleSelectActionType}
                                disabled={true}
                            />
                        </div>
                        {currentAction.actionType === 'worker' &&
                            <WorkerAction
                                loadCapacity={{
                                    value: loadCapacity,
                                    min: 1,
                                    max: 5,
                                    step: 1,
                                    defaultValue: "10",
                                    disabled: true,
                                    onChange: handleLoadCapacityChange,
                                }}
                                clearPoints={handleClearPoints}
                            />
                        }
                        {currentAction.actionType === 'assembly' &&
                            <AssemblyAction
                                processTime={{
                                    value: processTime,
                                    min: 1,
                                    max: 60,
                                    onChange: handleProcessTimeChange,
                                }}
                                swapOptions={["Default material", "Material 1", "Material 2", "Material 3"]}
                                swapDefaultOption={swappedMaterial}
                                onSwapSelect={handleMaterialChange}
                            />
                        }
                        <div className="tirgger">
                            <Trigger selectedPointData={selectedPointData as any} type="Human" />
                        </div>
                    </div>
                )}
            </section>
        </>
    );
}

export default HumanMechanics;