import * as React from "react";
import { TreeNodeProps } from "./tree-node";

//DataNode types
interface DataNode {
  children?: DataNode[];
  isLeaf?: boolean;
  icon?: IconType;
  switcherIcon?: IconType;
  key?: string | number;
  title?: React.ReactNode;
  selectable?: boolean;
  disabled?: boolean;

  //Set style of TreeNode.
  //This is not recommend if you don't have force requirement.
  className?: string;
  style?: React.CSSProperties;
}

//EventDataNode types
interface EventDataNode extends DataNode {
  expanded: boolean;
  selected: boolean;
  loaded: boolean;
  loading: boolean;
  dragOver: boolean;
  dragOverGapTop: boolean;
  dragOverGapBottom: boolean;
  pos: string;
  active: boolean;
}

//Icon Type
type IconType = React.ReactNode | ((props: TreeNodeProps) => React.ReactNode);

//key
type Key = string | number;

//Node Element
type NodeElement = React.ReactElement<TreeNodeProps> & {
  selectHandle?: HTMLSpanElement;
  type: {
    isTreeNode: boolean;
  };
};

//Node Instance
type NodeInstance = React.Component<TreeNodeProps> & {
  selectHandle?: HTMLSpanElement;
};

//Entity
interface Entity {
  node: NodeElement;
  index: number;
  pos: string;
  key: Key;
  parent?: Entity;
  children?: Entity[];
}

//Data Entity
interface DataEntity extends Omit<Entity, "node" | "parent" | "children"> {
  node: DataNode;
  parent?: DataEntity;
  children?: DataEntity[];
  level: number;
}

//Flatten Node
interface FlattenNode {
  parent: FlattenNode | null;
  children: FlattenNode[];
  pos: string;
  data: DataNode;
  isStart: boolean[];
  isEnd: boolean[];
}

type ScrollTo = (scroll: { key: Key }) => void;

export {
  DataNode,
  EventDataNode,
  IconType,
  Key,
  NodeElement,
  NodeInstance,
  Entity,
  DataEntity,
  FlattenNode,
  ScrollTo,
};
