import {
  SystemRole,
  SystemRoleAttribute,
  TransactionType,
} from '@/utils/role.util';
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
import { TreeSelectionKeys } from '../../../../node_modules/primevue/tree';
import { MenuItem } from '../Menu/MenuItem';

export interface TreeSystemRoles {
  group: SystemRole;
}

export interface TreeNode {
  /**
   * Mandatory unique key of the node.
   */
  key?: string;
  /**
   * Label of the node.
   */
  label?: string;
  /**
   * Data represented by the node.
   */
  data?: any;
  hasSystemRoles?: TreeSystemRoles;
  /**
   * Type of the node to match a template.
   */
  type?: string;
  /**
   * Icon of the node to display next to content.
   */
  icon?: string;
  /**
   * An array of treenodes as children.
   */
  children?: TreeNode[];
  /**
   * Inline style of the node.
   */
  style?: any;
  /**
   * Style class of the node.
   */
  styleClass?: string;
  /**
   * Whether the node is selectable when selection mode is enabled.
   * @defaultValue false
   */
  selectable?: boolean;
  /**
   * Specifies if the node has children. Used in lazy loading.
   * @defaultValue false
   */
  leaf?: boolean;
  /**
   * Specifies the node loading. Used in Tree and TreeTable.
   */
  loading?: boolean;
  /**
   * Icon to use in expanded state.
   */
  expandedIcon?: string;
  /**
   * Icon to use in collapsed state.
   */
  collapsedIcon?: string;
  /**
   * Optional
   */
  [key: string]: any;
}

export interface TreeProps {
  type: 'Group' | 'Category';
  selectedKeys?: TreeSelectionKeys | string[] | undefined;
  selectedTreeNodes?: TreeNode[] | undefined;
  selectionMode?: 'single' | 'checkbox' | undefined;
  /**
   * Wether show node button action or not.
   *
   * @default false;
   */
  useOption?: boolean;
  /**
   * Keyword to filter the Tree by name/label.
   */
  filter: string;
  treeNodeMenus?: MenuItem[];
  /**
   * Specify wether the all tree node should be auto checked once it rendered.
   * @default false
   */
  autoSelectAll?: boolean;
  selectLastNode?: boolean;
  /**
   * Disable node 'All' selection
   */
  disableNodeAll?: boolean;
  /**
   * Disable level 2 (All > Level 1 > Level 2)
   */
  disableSubChildren?: boolean;
  /**
   * Include node All key (-1) on Checkbox Selection
   *
   * @default false - (-1) is excluded
   */
  includeNodeAllKey?: boolean;
  disableKeys?: number[];
  exactDisableKey?: number;
  /**
   * Defines the tree is readonly and disabled.
   */
  readonly?: boolean;
  /**
   * Defines the tree to select disposable group only.
   */
  selectDisposableOnly?: boolean;
  /**
   * Defines the tree to be flattened and shows disposable only
   */
  flattenDisposableNode?: boolean;
  /**
   * Set custom query params for group tree.
   *
   * By default, query params has been determined by the path
   */
  groupParams?: TreeQueryParams;
  /**
   * Defines the group tree to disable excluded keys
   */
  excludedKeys?: string[];
  /**
   * Specifies the required manager transaction permission to make a node selectable.
   * If the node's `manager[transaction]` value is false, the node will be rendered in a disabled state.
   */
  requiredManagerPermission?: TransactionType;
  /**
   * Specifies the required system role permission to make a node selectable.
   * If the node's `SystemRoleAttribute[SystemRole]` value is false, the node will be rendered in a disabled state.
   */
  requiredSystemRole?: [SystemRoleAttribute, keyof SystemRole];
}

export type TreeEmits = {
  'update:selectedKeys': [keys: TreeSelectionKeys];
  'update:selectedTreeNodes': [nodes: TreeNode[] | undefined];
  'nodeSelect': [node: TreeNode];
  'nodeUnselect': [node: TreeNode];
  'toggleMenu': [node: TreeNode];
};

/**
 * **TSVue v2 - Tree**
 *
 * _Tree is used to display hierarchical data._
 *
 * --- ---
 * ![TSVue](https://ik.imagekit.io/kurniadev/TS-HEAD-BLACK.png)
 *
 * @group Component
 */
declare class Tree extends ClassComponent<TreeProps, TreeSlots, TreeEmits> {
  /**
   * The Tree Node array.
   */
  treeNodes: TreeNode[];
  /**
   * Tree Nodes loading state.
   */
  isLoading: boolean;
  /**
   * Show disposable group icon.
   */
  showDisposableGroups: boolean;
  /**
   * Show group available quota.
   */
  showAvailableQuota: boolean;
  /**
   * State where all tree node expanded.
   */
  isExpandedAll: boolean;
  /**
   * Method to collapse all node.
   */
  collapseAll: () => void;
  /**
   * Method to expand all node.
   */
  expandAll: () => void;
  /**
   * Expand the All node to show all Parent Group
   */
  expandNodeAll: () => void;
  /**
   * Trigger fetch tree list
   */
  fetchTreeList: () => void;
}

declare module '@vue/runtime-core' {
  interface GlobalComponents {
    Tree: GlobalComponentConstructor<Tree>;
  }
}

export default Tree;
