import React, { useEffect, useRef, useState } from "react";
import { AddIcon, ArrowIcon, RemoveIcon, ResizeHeightIcon } from "../../../icons/ExportCommonIcons";
import RenameInput from "../../../ui/inputs/RenameInput";
import { handleResize } from "../../../../functions/handleResizePannel";
import { useSimulationState, useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
import { generateUUID } from "three/src/math/MathUtils";
import RenderOverlay from "../../../templates/Overlay";
import EditWidgetOption from "../../../ui/menu/EditWidgetOption";
import { handleAddEventToProduct } from "../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
import { deleteEventDataApi } from "../../../../services/simulation/products/deleteEventDataApi";
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
import { deleteProductApi } from "../../../../services/simulation/products/deleteProductApi";
import { renameProductApi } from "../../../../services/simulation/products/renameProductApi";
import { determineExecutionMachineSequences } from "../../../../modules/simulation/simulator/functions/determineExecutionMachineSequences";
import ComparePopUp from "../../../ui/compareVersion/Compare";
import { useCompareStore, useIsComparing, useSimulateId } from "../../../../store/builder/store";
import { useToggleStore } from "../../../../store/ui/useUIToggleStore";
import { useParams } from "react-router-dom";
import { useSceneContext } from "../../../../modules/scene/sceneContext";
import { updateSimulateData } from "../../scenes/functions/simulationStorage";

interface Event {
    modelName: string;
    modelId: string;
}

const Simulations: React.FC = () => {
    const productsContainerRef = useRef<HTMLDivElement>(null);
    const { eventStore, productStore, versionStore } = useSceneContext();
    const { products, addProduct, removeProduct, renameProduct, addEvent, removeEvent, getProductById, selectedProduct, setSelectedProduct } = productStore();
    const { getEventByModelUuid } = eventStore();
    const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
    const [openObjects, setOpenObjects] = useState(true);
    const [processes, setProcesses] = useState<Event[][]>();
    const { setToggleUI } = useToggleStore();
    const { projectId } = useParams();
    const { setMainState, clearMainState } = useSimulationState();
    const { selectedVersion } = versionStore();
    const { comparePopUp, setComparePopUp } = useCompareStore();
    const { setIsComparing } = useIsComparing();
    const { simulateId } = useSimulateId();

    const handleSaveVersion = async () => {
        setIsComparing(true);
        setComparePopUp(false);
        setToggleUI(false, false);
        const singleData = {
            projectId: projectId,
            versionId: selectedVersion?.versionId || "",
            productUuid: selectedProduct?.productUuid || "",
            simulatedId: simulateId,
        };
        const getData = await updateSimulateData(singleData);
        echo.log(getData.message);
    };

    const handleAddProduct = () => {
        const id = generateUUID();
        const name = `Product ${products.length + 1}`;
        addProduct(name, id);
        upsertProductOrEventApi({
            productName: name,
            productUuid: id,
            projectId: projectId,
            versionId: selectedVersion?.versionId || "",
        });
    };

    const handleRemoveProduct = (productUuid: string) => {
        const currentIndex = products.findIndex((p) => p.productUuid === productUuid);
        const isSelected = selectedProduct.productUuid === productUuid;

        const updatedProducts = products.filter((p) => p.productUuid !== productUuid);

        if (isSelected && selectedVersion) {
            if (updatedProducts.length > 0) {
                let newSelectedIndex = currentIndex;
                if (currentIndex >= updatedProducts.length) {
                    newSelectedIndex = updatedProducts.length - 1;
                }
                setSelectedProduct(updatedProducts[newSelectedIndex].productUuid, updatedProducts[newSelectedIndex].productName);
                const data = {
                    productUuid: updatedProducts[newSelectedIndex].productUuid,
                    productName: updatedProducts[newSelectedIndex].productName,
                    versionUuid: selectedVersion.versionId,
                    versionName: selectedVersion.versionName,
                };
                setMainState(data);
            } else {
                setSelectedProduct("", "");
                clearMainState();
            }
        }

        removeProduct(productUuid);
        deleteProductApi({
            productUuid,
            versionId: selectedVersion?.versionId || "",
            projectId,
        });
    };

    const handleRenameProduct = (productUuid: string, newName: string) => {
        renameProduct(productUuid, newName);
        renameProductApi({ productName: newName, productUuid, projectId: projectId || "", versionId: selectedVersion?.versionId || "" });
        if (selectedProduct.productUuid === productUuid && selectedVersion) {
            setSelectedProduct(productUuid, newName);
            const data = {
                productUuid: productUuid,
                productName: newName,
                versionUuid: selectedVersion.versionId,
                versionName: selectedVersion.versionName,
            };
            setMainState(data);
        }
    };

    const handleRemoveEventFromProduct = () => {
        if (selectedAsset) {
            deleteEventDataApi({
                productUuid: selectedProduct.productUuid,
                modelUuid: selectedAsset.modelUuid,
                versionId: selectedVersion?.versionId || "",
                projectId: projectId,
            });
            removeEvent(selectedProduct.productUuid, selectedAsset.modelUuid);
            clearSelectedAsset();
        }
    };

    useEffect(() => {
        const processes: Event[][] = [];
        const selectedProductData = getProductById(selectedProduct.productUuid);

        if (selectedProductData) {
            determineExecutionMachineSequences([selectedProductData]).then((sequences) => {
                sequences.forEach((sequence) => {
                    const events: Event[] =
                        sequence.map((event) => ({
                            modelName: event.modelName,
                            modelId: event.modelUuid,
                        })) || [];
                    processes.push(events);
                });
                setProcesses(processes);
            });
        }
    }, [selectedProduct.productUuid, products]);

    useEffect(() => {
        if (comparePopUp || selectedProduct.productUuid) {
        }
    }, [comparePopUp]);

    const getSimulate = async () => {
        // const singleData = {
        //     projectId: projectId,
        //     versionId: selectedVersion?.versionId || "",
        //     productUuid: selectedProduct?.productUuid || "",
        // };
        // console.log("singleData: ", singleData);
        // const getData = await getSimulationData(singleData);
        // console.log("getData: ", getData);
        setComparePopUp(true);
    };

    return (
        <div className="simulations-container">
            <div className="header">Simulations</div>
            <div className="add-product-container">
                <div className="actions section">
                    <div className="header">
                        <div className="header-value">Products</div>
                        <button id="add-simulation" className="add-button" onClick={handleAddProduct}>
                            <AddIcon /> Add
                        </button>
                    </div>
                    <div className="lists-main-container" ref={productsContainerRef} style={{ height: "120px" }}>
                        <div className="list-container">
                            {products.map((product, index) => (
                                <div key={product.productUuid} className={`list-item ${selectedProduct.productUuid === product.productUuid ? "active" : ""}`}>
                                    {/* eslint-disable-next-line */}
                                    <div
                                        className="value"
                                        onClick={() => {
                                            if (selectedVersion) {
                                                setSelectedProduct(product.productUuid, product.productName);
                                                const data = {
                                                    productUuid: product.productUuid,
                                                    productName: product.productName,
                                                    versionUuid: selectedVersion.versionId,
                                                    versionName: selectedVersion.versionName,
                                                };
                                                setMainState(data);
                                            }
                                        }}
                                    >
                                        <input type="radio" name="products" checked={selectedProduct.productUuid === product.productUuid} readOnly />
                                        <RenameInput value={product.productName} onRename={(newName) => handleRenameProduct(product.productUuid, newName)} />
                                    </div>
                                    {products.length > 1 && (
                                        <button id="remove-product-button" className="remove-button" onClick={() => handleRemoveProduct(product.productUuid)}>
                                            <RemoveIcon />
                                        </button>
                                    )}
                                </div>
                            ))}
                        </div>
                        <button className="resize-icon" id="action-resize" onMouseDown={(e: any) => handleResize(e, productsContainerRef)}>
                            <ResizeHeightIcon />
                        </button>
                    </div>
                </div>

                <div className="simulation-process section">
                    <button id="collapse-header" className="collapse-header-container" onClick={() => setOpenObjects(!openObjects)}>
                        <div className="header">Process Flow</div>
                        <div className="arrow-container">
                            <ArrowIcon />
                        </div>
                    </button>
                    {openObjects &&
                        processes?.map((process, index) => (
                            <section key={index}>
                                {process.map((event, index) => (
                                    <div className="process-container" key={index}>
                                        <div className="value">{event.modelName}</div>
                                    </div>
                                ))}
                            </section>
                        ))}
                </div>

                <div className="compare-simulations-container">
                    <div className="compare-simulations-header">Need to Compare Layout?</div>
                    <div className="content">
                        Click '<span>Compare</span>' to review and analyze the layout differences between them.
                    </div>
                    <button
                        className="input"
                        onClick={() => {
                            // setComparePopUp(true);
                            getSimulate();
                        }}
                    >
                        <input type="button" value={"Compare"} className="submit" />
                    </button>
                </div>
            </div>

            {selectedAsset && (
                <RenderOverlay>
                    <EditWidgetOption
                        options={["Add to Product", "Remove from Product"]}
                        onClick={(option) => {
                            if (option === "Add to Product") {
                                handleAddEventToProduct({
                                    event: getEventByModelUuid(selectedAsset.modelUuid),
                                    addEvent,
                                    selectedProduct,
                                    clearSelectedAsset,
                                    projectId: projectId || "",
                                    versionId: selectedVersion?.versionId || "",
                                });
                            } else {
                                handleRemoveEventFromProduct();
                            }
                        }}
                    />
                </RenderOverlay>
            )}

            {comparePopUp && (
                <RenderOverlay>
                    <ComparePopUp onClose={handleSaveVersion} />
                </RenderOverlay>
            )}
        </div>
    );
};

export default Simulations;
