import "../../style/steps_tree.css"
import { StepInfoNode } from "../../model/tactic/Tactic"
import BendableArrow from "../arrows/BendableArrow"
import { ReactNode, useMemo, useRef } from "react"
import AddSvg from "../../assets/icon/add.svg?react"
import RemoveSvg from "../../assets/icon/remove.svg?react"
import { getStepName } from "../../domains/StepsDomain.ts"

export interface StepsTreeProps {
    root: StepInfoNode
    selectedStepId: number
    onAddChildren?: (parent: StepInfoNode) => void
    onRemoveNode?: (node: StepInfoNode) => void
    onStepSelected?: (node: StepInfoNode) => void
}

export default function StepsTree({
                                      root,
                                      selectedStepId,
                                      onAddChildren,
                                      onRemoveNode,
                                      onStepSelected,
                                  }: StepsTreeProps) {
    return (
        <div className="steps-tree">
            <StepsTreeNode
                node={root}
                rootNode={root}
                selectedStepId={selectedStepId}
                onAddChildren={onAddChildren}
                onRemoveNode={onRemoveNode}
                onStepSelected={onStepSelected}
            />
        </div>
    )
}

interface StepsTreeContentProps {
    node: StepInfoNode
    rootNode: StepInfoNode

    selectedStepId: number
    onAddChildren?: (parent: StepInfoNode) => void
    onRemoveNode?: (node: StepInfoNode) => void
    onStepSelected?: (node: StepInfoNode) => void
}

function StepsTreeNode({
                           node,
                           rootNode,
                           selectedStepId,
                           onAddChildren,
                           onRemoveNode,
                           onStepSelected,
                       }: StepsTreeContentProps) {
    const ref = useRef<HTMLDivElement>(null)

    return (
        <div ref={ref} className={"step-group"}>
            {node.children.map((child) => (
                <BendableArrow
                    key={child.id}
                    area={ref}
                    startPos={"step-piece-" + node.id}
                    segments={[
                        {
                            next: "step-piece-" + child.id,
                        },
                    ]}
                    onSegmentsChanges={() => {
                    }}
                    forceStraight={true}
                    wavy={false}
                    readOnly={true}
                    //TODO remove magic constants
                    startRadius={10}
                    endRadius={10}
                />
            ))}
            <StepPiece
                id={node.id}
                isSelected={selectedStepId === node.id}
                onAddButtonClicked={onAddChildren
                    ? () => onAddChildren(node)
                    : undefined
                }
                onRemoveButtonClicked={
                    rootNode.id === node.id || !onRemoveNode
                        ? undefined
                        : () => onRemoveNode(node)
                }
                onSelected={() => {
                    if (onStepSelected) onStepSelected(node)
                }}>
                <p>
                    {useMemo(
                        () => getStepName(rootNode, node.id),
                        [node.id, rootNode],
                    )}
                </p>
            </StepPiece>
            <div className={"step-children"}>
                {node.children.map((child) => (
                    <StepsTreeNode
                        key={child.id}
                        rootNode={rootNode}
                        selectedStepId={selectedStepId}
                        node={child}
                        onAddChildren={onAddChildren}
                        onRemoveNode={onRemoveNode}
                        onStepSelected={onStepSelected}
                    />
                ))}
            </div>
        </div>
    )
}

interface StepPieceProps {
    id: number
    isSelected: boolean
    onAddButtonClicked?: () => void
    onRemoveButtonClicked?: () => void
    onSelected: () => void
    children?: ReactNode
}

function StepPiece({
                       id,
                       isSelected,
                       onAddButtonClicked,
                       onRemoveButtonClicked,
                       onSelected,
                       children,
                   }: StepPieceProps) {
    return (
        <div
            id={"step-piece-" + id}
            tabIndex={1}
            className={
                "step-piece " + (isSelected ? "step-piece-selected" : "")
            }
            onClick={onSelected}>
            <div className="step-piece-actions">
                {onAddButtonClicked && (
                    <AddSvg
                        onClick={onAddButtonClicked}
                        className={"add-icon"}
                    />
                )}
                {onRemoveButtonClicked && (
                    <RemoveSvg
                        onClick={onRemoveButtonClicked}
                        className={"remove-icon"}
                    />
                )}
            </div>
            {children}
        </div>
    )
}
