import { Container, bindable, computedFrom } from "aurelia-framework";
import { UITreeNode } from "../ui-tree-model";
import { UITreePanel } from "./ui-tree-panel";
import { customElement } from "aurelia-templating";
import { IMenuItems } from "../../menu/ui-menus";
import { I18N } from "aurelia-i18n";

@customElement("tree-node")
export class TreeNode<TTargetEntity> {
  @bindable()
  public node: UITreeNode;
  @bindable()
  public index: number;
  @bindable()
  protected tree: UITreePanel<TTargetEntity>;
  @bindable
  public showNodeExpand: boolean;

  get isSelected(): boolean {
    return (this.node && this.tree.value.indexOf(this.node.id) > -1);
  }
  private i18n: I18N;
  constructor() {
    this.i18n = Container.instance.get(I18N);
  }

  @computedFrom('node.level', 'node.id')
  get linesClassesPerLevel(): string[] {
    let classes: string[] = [];

    if (false == this.tree.treeConfig?.withLines) {
      return classes;
    }

    for (let level = 1; level <= this.node.level; ++level) {
      let cls = this.node.id == 'node-empty' ? '' : (level == this.node.level ? 'ui-tree__spacer__lines' : 'ui-tree__spacer__vertical');
      if (cls == 'ui-tree__spacer__vertical') {
        // Check if vertical line is needed: if parent of parent (grandparent) has child after parent, checking on requested level
        let goUp = this.node.level - level;
        let parent = this.node;
        while (goUp > 0) {
          parent = parent.parent;
          --goUp;
        }
        let grandparent = parent.parent;
        // Check if parent is last child of grandparent
        if (parent.id == grandparent.childNodes.last().id) {
          cls = '';
        }
      }
      classes.push(cls);
    }
    return classes;
  }

  @computedFrom('node.dropdownActions.length')
  get dropdownMenuItems(): Array<IMenuItems> {
    let menuItems: Array<IMenuItems> = [];
    this.node.dropdownActions?.forEach(x => {
      menuItems.push({
        label: this.i18n.tr(x.getLabel(this.node)),
        icon: x.icon,
        color: x.color,
        iconColor: x.iconColor,
        handler: async () => {
          x.fn.call(x, this.node);
        },
        classes: x.classes
      } as IMenuItems);
    })
    return menuItems;
  }
}
