package fr.titionfire.ffsaf.domain.entity;

import fr.titionfire.ffsaf.data.model.TreeModel;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
@RegisterForReflection
public class TreeEntity {
    private Long id;
    private Long categorie;
    private Integer level;
    private MatchEntity match;
    private TreeEntity left;
    private TreeEntity right;
    private TreeEntity associatedNode;

    public static TreeEntity fromModel(TreeModel model) {
        if (model == null)
            return null;

        return new TreeEntity(model.getId(), model.getCategory(), model.getLevel(), MatchEntity.fromModel(model.getMatch()), fromModel(model.getLeft()),
                fromModel(model.getRight()), null);
    }

    public TreeEntity getMatchNode(Long matchId) {
        if (this.match != null && this.match.getId() == matchId) {
            return this;
        } else {
            if (this.left != null) {
                TreeEntity left = this.left.getMatchNode(matchId);
                if (left != null) {
                    return left;
                }
            }
            if (this.right != null) {
                TreeEntity right = this.right.getMatchNode(matchId);
                if (right != null) {
                    return right;
                }
            }
        }
        return null;
    }

    public static TreeEntity getParent(TreeEntity current, TreeEntity target) {
        if (current == null) {
            return null;
        } else if (current.equals(target)) {
            return null;
        } else if (target.equals(current.left) || target.equals(current.right)) {
            return current;
        } else {
            TreeEntity left = getParent(current.left, target);
            if (left != null)
                return left;
            return getParent(current.right, target);
        }
    }

    public static void setAssociated(TreeEntity current, TreeEntity next) {
        if (current == null || next == null) {
            return;
        }
        current.setAssociatedNode(next);
        setAssociated(current.getLeft(), next.getLeft());
        setAssociated(current.getRight(), next.getRight());
    }
}
