import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
import { ArrowIcon } from "../../../icons/ExportCommonIcons";

// image imports
import Arc from "../../../../assets/image/aisleTypes/Arc.png";
import Arrow from "../../../../assets/image/aisleTypes/Arrow.png";
import Arrows from "../../../../assets/image/aisleTypes/Arrows.png";
import Circle from "../../../../assets/image/aisleTypes/Circle.png";
import Dashed from "../../../../assets/image/aisleTypes/Dashed.png";
import Directional from "../../../../assets/image/aisleTypes/Directional.png";
import Dotted from "../../../../assets/image/aisleTypes/Dotted.png";
import Solid from "../../../../assets/image/aisleTypes/Solid.png";
import InputToggle from "../../../ui/inputs/InputToggle";
import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
import { useSceneContext } from "../../../../modules/scene/sceneContext";
import { useSocketStore } from "../../../../store/builder/store";
import { getUserData } from "../../../../functions/getUserData";
import { aisleTextureList } from "./AisleProperties";

import { upsertAisleApi } from "../../../../services/factoryBuilder/aisle/upsertAisleApi";

const SelectedAisleProperties: React.FC = () => {
    const [collapsePresets, setCollapsePresets] = useState(false);
    const [collapseTexture, setCollapseTexture] = useState(true);
    const { aisleStore, versionStore } = useSceneContext();
    const { getAisleById, updateAisle, setDashedAisleProperties, setDottedAisleProperties, setArrowsAisleProperties, setArcAisleWidth, setColor } = aisleStore();
    const { selectedVersion } = versionStore();
    const { socket } = useSocketStore();
    const { userId, organization } = getUserData();
    const { projectId } = useParams();
    const [selectedAisleData, setSelectedAisleData] = useState<Aisle | undefined>();

    const { selectedAisle, setSelectedAisle } = useBuilderStore();

    useEffect(() => {
        const aisleData = getAisleById(selectedAisle?.aisleMesh?.uuid || "");
        setSelectedAisleData(aisleData);
    }, [selectedAisle, getAisleById]);

    if (!selectedAisleData) return null;

    const updateBackend = (updatedAisle: Aisle) => {
        if (updatedAisle && projectId) {

            if (!socket?.connected) {

                // API

                upsertAisleApi(updatedAisle.aisleUuid, updatedAisle.points, updatedAisle.type, projectId, selectedVersion?.versionId || '');

            } else {

                // SOCKET

                const data = {
                    projectId: projectId,
                    versionId: selectedVersion?.versionId || '',
                    userId: userId,
                    organization: organization,
                    aisleUuid: updatedAisle.aisleUuid,
                    points: updatedAisle.points,
                    type: updatedAisle.type
                }

                socket.emit('v1:model-aisle:add', data);
            }
        }
    }

    const aisleTypes: {
        name: string;
        type: AisleTypes;
        id: string;
        thumbnail: string;
    }[] = [
            { name: "Solid", type: "solid-aisle", id: "1", thumbnail: Solid },
            { name: "Dotted", type: "dotted-aisle", id: "2", thumbnail: Dotted },
            { name: "Dashed", type: "dashed-aisle", id: "3", thumbnail: Dashed },
            { name: "Arrow", type: "arrow-aisle", id: "4", thumbnail: Arrow },
            { name: "Continuous Arrows", type: "arrows-aisle", id: "5", thumbnail: Arrows },
            { name: "Directional", type: "junction-aisle", id: "6", thumbnail: Directional },
            { name: "Arc", type: "arc-aisle", id: "7", thumbnail: Arc },
            { name: "Circle", type: "circle-aisle", id: "8", thumbnail: Circle },
        ];

    const createAisleTypeObject = (newType: AisleTypes, currentType: AisleType): AisleType => {
        switch (newType) {
            case 'solid-aisle':
                return {
                    aisleType: 'solid-aisle',
                    aisleColor: currentType.aisleColor,
                    aisleWidth: 'aisleWidth' in currentType ? currentType.aisleWidth : 0.1
                } as SolidAisle;

            case 'dashed-aisle':
                return {
                    aisleType: 'dashed-aisle',
                    aisleColor: currentType.aisleColor,
                    aisleWidth: 'aisleWidth' in currentType ? currentType.aisleWidth : 0.1,
                    dashLength: 'dashLength' in currentType ? (currentType as DashedAisle).dashLength : 0.5,
                    gapLength: 'gapLength' in currentType ? (currentType as DashedAisle).gapLength : 0.3
                } as DashedAisle;

            case 'dotted-aisle':
                return {
                    aisleType: 'dotted-aisle',
                    aisleColor: currentType.aisleColor,
                    dotRadius: 'dotRadius' in currentType ? (currentType as DottedAisle).dotRadius : 0.1,
                    gapLength: 'gapLength' in currentType ? (currentType as DottedAisle).gapLength : 0.3
                } as DottedAisle;

            case 'arrow-aisle':
                return {
                    aisleType: 'arrow-aisle',
                    aisleColor: currentType.aisleColor,
                    aisleWidth: 'aisleWidth' in currentType ? currentType.aisleWidth : 0.1
                } as ArrowAisle;

            case 'arrows-aisle':
                return {
                    aisleType: 'arrows-aisle',
                    aisleColor: currentType.aisleColor,
                    aisleWidth: 'aisleWidth' in currentType ? currentType.aisleWidth : 0.1,
                    aisleLength: 'aisleLength' in currentType ? (currentType as ArrowsAisle).aisleLength : 0.6,
                    gapLength: 'gapLength' in currentType ? (currentType as ArrowsAisle).gapLength : 0.3
                } as ArrowsAisle;

            case 'arc-aisle':
                return {
                    aisleType: 'arc-aisle',
                    aisleColor: currentType.aisleColor,
                    aisleWidth: 'aisleWidth' in currentType ? currentType.aisleWidth : 0.1,
                    isFlipped: 'isFlipped' in currentType ? (currentType as ArcAisle).isFlipped : false
                } as ArcAisle;

            case 'circle-aisle':
                return {
                    aisleType: 'circle-aisle',
                    aisleColor: currentType.aisleColor,
                    aisleWidth: 'aisleWidth' in currentType ? currentType.aisleWidth : 0.1
                } as CircleAisle;

            case 'junction-aisle':
                return {
                    aisleType: 'junction-aisle',
                    aisleColor: currentType.aisleColor,
                    aisleWidth: 'aisleWidth' in currentType ? currentType.aisleWidth : 0.1,
                    isFlipped: 'isFlipped' in currentType ? (currentType as JunctionAisle).isFlipped : false
                } as JunctionAisle;

            default:
                return {
                    aisleType: 'solid-aisle',
                    aisleColor: currentType.aisleColor,
                    aisleWidth: 0.1
                } as SolidAisle;
        }
    };

    const handleAisleTypeChange = (newType: AisleTypes) => {
        if (!selectedAisle?.aisleData) return;
        const newAisleType = createAisleTypeObject(newType, selectedAisleData.type);

        const updatedAisle = updateAisle(selectedAisleData.aisleUuid, {
            type: newAisleType
        });

        setSelectedAisle({ aisleData: selectedAisle.aisleData, aisleMesh: null });

        setSelectedAisleData({
            ...selectedAisleData,
            type: newAisleType
        });

        if (updatedAisle) {
            updateBackend(updatedAisle);
        }
    };

    const handleColorChange = (value: AisleColors) => {
        const updatedAisle = setColor(selectedAisleData.aisleUuid, value);

        setSelectedAisleData({
            ...selectedAisleData,
            type: {
                ...selectedAisleData.type,
                aisleColor: value
            }
        })

        if (updatedAisle) {
            updateBackend(updatedAisle);
        }
    };

    const handleAisleWidthChange = (value: string) => {
        const width = parseFloat(value);
        if (!isNaN(width) && selectedAisleData.type.aisleType !== 'dotted-aisle') {
            const updatedAisle = updateAisle(selectedAisleData.aisleUuid, {
                type: {
                    ...selectedAisleData.type,
                    aisleWidth: width
                }
            });

            setSelectedAisleData({
                ...selectedAisleData,
                type: {
                    ...selectedAisleData.type,
                    aisleWidth: width
                }
            })

            if (updatedAisle) {
                updateBackend(updatedAisle);
            }
        }
    };

    const handleDashLengthChange = (value: string) => {
        const length = parseFloat(value);
        if (!isNaN(length) && selectedAisleData.type.aisleType === 'dashed-aisle') {
            const updatedAisle = setDashedAisleProperties(selectedAisleData.aisleUuid, {
                dashLength: length
            });

            setSelectedAisleData({
                ...selectedAisleData,
                type: {
                    ...(selectedAisleData.type as DashedAisle),
                    dashLength: length
                }
            })

            if (updatedAisle) {
                updateBackend(updatedAisle);
            }
        }
    };

    const handleGapLengthChange = (value: string) => {
        const length = parseFloat(value);
        if (!isNaN(length) && (selectedAisleData.type.aisleType === 'dashed-aisle' || selectedAisleData.type.aisleType === 'dotted-aisle' || selectedAisleData.type.aisleType === 'arrows-aisle')) {
            if (selectedAisleData.type.aisleType === 'dashed-aisle') {
                const updatedAisle = setDashedAisleProperties(selectedAisleData.aisleUuid, {
                    gapLength: length
                });

                setSelectedAisleData({
                    ...selectedAisleData,
                    type: {
                        ...(selectedAisleData.type as DashedAisle),
                        gapLength: length
                    }
                })

                if (updatedAisle) {
                    updateBackend(updatedAisle);
                }
            } else if (selectedAisleData.type.aisleType === 'dotted-aisle') {
                const updatedAisle = setDottedAisleProperties(selectedAisleData.aisleUuid, {
                    gapLength: length
                });

                setSelectedAisleData({
                    ...selectedAisleData,
                    type: {
                        ...(selectedAisleData.type as DottedAisle),
                        gapLength: length
                    }
                })

                if (updatedAisle) {
                    updateBackend(updatedAisle);
                }
            } else if (selectedAisleData.type.aisleType === 'arrows-aisle') {
                const updatedAisle = setArrowsAisleProperties(selectedAisleData.aisleUuid, {
                    gapLength: length
                });

                setSelectedAisleData({
                    ...selectedAisleData,
                    type: {
                        ...(selectedAisleData.type as ArrowsAisle),
                        gapLength: length
                    }
                })

                if (updatedAisle) {
                    updateBackend(updatedAisle);
                }
            }
        }
    };

    const handleDotRadiusChange = (value: string) => {
        const radius = parseFloat(value);
        if (!isNaN(radius) && selectedAisleData.type.aisleType === 'dotted-aisle') {
            const updatedAisle = setDottedAisleProperties(selectedAisleData.aisleUuid, {
                dotRadius: radius
            });

            setSelectedAisleData({
                ...selectedAisleData,
                type: {
                    ...(selectedAisleData.type as DottedAisle),
                    dotRadius: radius
                }
            })

            if (updatedAisle) {
                updateBackend(updatedAisle);
            }
        }
    };

    const handleAisleLengthChange = (value: string) => {
        const length = parseFloat(value);
        if (!isNaN(length) && selectedAisleData.type.aisleType === 'arrows-aisle') {
            const updatedAisle = setArrowsAisleProperties(selectedAisleData.aisleUuid, {
                aisleLength: length
            });

            setSelectedAisleData({
                ...selectedAisleData,
                type: {
                    ...(selectedAisleData.type as ArrowsAisle),
                    aisleLength: length
                }
            })

            if (updatedAisle) {
                updateBackend(updatedAisle);
            }
        }
    };

    const handleIsFlippedChange = () => {
        if (selectedAisleData.type.aisleType === 'arc-aisle' || selectedAisleData.type.aisleType === 'junction-aisle') {
            const currentType = selectedAisleData.type as ArcAisle | JunctionAisle;
            const currentFlipped = currentType.isFlipped || false;
            const updatedAisle = setArcAisleWidth(selectedAisleData.aisleUuid, {
                isFlipped: !currentFlipped
            });

            setSelectedAisleData({
                ...selectedAisleData,
                type: {
                    ...currentType,
                    isFlipped: !currentFlipped
                }
            })

            if (updatedAisle) {
                updateBackend(updatedAisle);
            }
        }
    };

    const renderAdvancedProperties = () => {
        switch (selectedAisleData.type.aisleType) {
            case 'dashed-aisle':
                const dashedType = selectedAisleData.type as DashedAisle;
                return (
                    <>
                        <InputWithDropDown
                            label="Dash Length"
                            value={`${dashedType.dashLength}`}
                            min={0.1}
                            step={0.1}
                            max={2}
                            onChange={handleDashLengthChange}
                        />
                        <InputWithDropDown
                            label="Gap Length"
                            value={`${dashedType.gapLength}`}
                            min={0.1}
                            step={0.1}
                            max={2}
                            onChange={handleGapLengthChange}
                        />
                    </>
                );
            case 'dotted-aisle':
                const dottedType = selectedAisleData.type as DottedAisle;
                return (
                    <>
                        <InputWithDropDown
                            label="Dot Radius"
                            value={`${dottedType.dotRadius}`}
                            min={0.1}
                            step={0.1}
                            max={2}
                            onChange={handleDotRadiusChange}
                        />
                        <InputWithDropDown
                            label="Gap Length"
                            value={`${dottedType.gapLength}`}
                            min={0.1}
                            step={0.1}
                            max={2}
                            onChange={handleGapLengthChange}
                        />
                    </>
                );
            case 'arrows-aisle':
                const arrowsType = selectedAisleData.type as ArrowsAisle;
                return (
                    <>
                        <InputWithDropDown
                            label="Arrow Length"
                            value={`${arrowsType.aisleLength}`}
                            min={0.1}
                            step={0.1}
                            max={2}
                            onChange={handleAisleLengthChange}
                        />
                        <InputWithDropDown
                            label="Gap Length"
                            value={`${arrowsType.gapLength}`}
                            min={0.1}
                            step={0.1}
                            max={2}
                            onChange={handleGapLengthChange}
                        />
                    </>
                );
            case 'junction-aisle':
            case 'arc-aisle':
                const flippedType = selectedAisleData.type as ArcAisle | JunctionAisle;
                return (
                    <InputToggle
                        inputKey="Flip Aisle"
                        label="Flip Aisle"
                        value={flippedType.isFlipped || false}
                        onClick={handleIsFlippedChange}
                    />
                );
            default:
                return null;
        }
    };

    return (
        <div className="aisle-properties-container">
            <div className="header">Properties</div>

            {/* Basic Properties */}
            <section>
                {selectedAisleData.type.aisleType !== 'dotted-aisle' &&
                    <InputWithDropDown
                        label="Aisle Width"
                        value={`${selectedAisleData.type.aisleWidth || 0.5}`}
                        min={0.1}
                        step={0.1}
                        max={2}
                        onChange={handleAisleWidthChange}
                    />
                }
                {renderAdvancedProperties()}
            </section>

            {/* Presets */}
            <section>
                <button
                    className="header"
                    onClick={() => setCollapsePresets(!collapsePresets)}
                    aria-expanded={!collapsePresets}
                >
                    <div className="value">Presets</div>
                    <div className="icon">
                        <ArrowIcon />
                    </div>
                </button>
                {!collapsePresets && (
                    <div className="presets-list-container">
                        {aisleTypes.map((val) => (
                            <div className="preset-list" key={val.id}>
                                <button
                                    className={`thumbnail ${selectedAisleData.type.aisleType === val.type ? "selected" : ""}`}
                                    title={val.name}
                                    onClick={() => handleAisleTypeChange(val.type)}
                                >
                                    <img src={val.thumbnail} alt="" />
                                </button>
                            </div>
                        ))}
                    </div>
                )}
            </section>

            {/* Texture */}
            <section>
                <button
                    className="header"
                    onClick={() => setCollapseTexture(!collapseTexture)}
                    aria-expanded={!collapseTexture}
                >
                    <div className="value">Aisle Texture</div>
                    <div className="icon" style={{ rotate: collapseTexture ? "" : "-90deg" }}>
                        <ArrowIcon />
                    </div>
                </button>

                {collapseTexture && (
                    <div className="aisle-texture-container">
                        {aisleTextureList.map((val) => (
                            <button
                                key={val.id}
                                title={val.brief || val.id}
                                className={`aisle-list ${selectedAisleData.type.aisleColor === val.id ? "selected" : ""}`}
                                onClick={() => handleColorChange(val.id)}
                                aria-pressed={selectedAisleData.type.aisleColor === val.id}
                            >
                                <div
                                    className={`texture-display ${val.id}`}
                                    style={{ background: val.id }}
                                >
                                    {val.texture}
                                </div>
                                <div className="aisle-color">{val.color}</div>
                                <div className="aisle-brief">{`( ${val.brief} )`}</div>
                            </button>
                        ))}
                    </div>
                )}
            </section>
        </div>
    );
};

export default SelectedAisleProperties;