import { TreeQueryParams } from '../../../services/tree.service';
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
import { TreeNode } from '../Tree/Tree.vue.d';
import { TSVueIconSeverities } from '../Icon/Icon.vue.d';
import { Severities } from '../../../utils/getSeverityByAssetStatus.util';
import {
  SystemRole,
  SystemRoleAttribute,
  TransactionType,
} from '@/utils/role.util';

export type KeysModelValue = string[] | undefined;

export interface ButtonSelectTreeProps {
  /**
   * Specify wether the all tree node should be auto checked once it rendered.
   * @default false
   */
  autoSelectAll?: boolean;
  /**
   * Customize button and badge severity
   *
   * @default undefined
   */
  severity?: Severities;
  /**
   * Determine whether severity of icon edit is inherited from main severity or defined separately
   *
   * @default undefined
   */
  iconEditSeverity?: TSVueIconSeverities;
  /**
   * Set custom query params for group tree.
   *
   * By default, query params has been determined by the path
   */
  groupParams?: TreeQueryParams;
  /**
   * The keys model value.
   * Keys also be used as field value. If you deal with form validation of edit action,
   * you need to bind the initital keys :keys="yourKeys"
   */
  keys?: KeysModelValue;
  disableKeys?: number[];
  /**
   * Disable the Select button
   */
  disabled?: boolean;
  exactDisableKey?: number;
  /**
   * Disable node 'All' selection
   */
  disableNodeAll?: boolean;
  /**
   * The selected tree nodes object model value.
   */
  selectedNodes?: TreeNode[];
  /**
   * Used for single selection model value.
   */
  selectedNode?: TreeNode;
  /**
   * For checkbox selection, old behavior is preventing select if there is no node selected.
   *
   * This props comes to make options, wether the selection can be empty or not.
   * @default true
   */
  allowEmptySelection?: boolean;
  /**
   * Set custom header Dialog Select Tree
   */
  dialogHeader?: string;
  /**
   * The tree type.
   */
  type: 'Group' | 'Category';
  /**
   * The button label.
   *
   * @default 'Select ${props.type}'
   */
  label?: string;
  /**
   * The field label
   */
  fieldLabel?: string;
  /**
   * The selection Mode.
   *
   * @default 'checkbox';
   */
  selectionMode?: 'single' | 'checkbox';
  /**
   * Wether the input should be validated with vee-validator or not.
   * If you use this component within form input, you need to set this props as true.
   */
  useValidator?: boolean;
  /**
   * This prop is required if you use this component in a form input.
   * Specify the unique field name, match with your needs for API request.
   *
   * @default 'selectTree'
   */
  fieldName?: string;
  /**
   * The information to be shown to user by hovering info icon.
   */
  fieldInfo?: string;
  /**
   * Make this field as mandatory on form input.
   */
  mandatory?: boolean;
  /**
   * Invalid state.
   */
  invalid?: boolean;
  /**
   * Set custom validator message.
   * Will be show if invalid="true"
   */
  validatorMessage?: string;
  /**
   * Defines width of button for 'Select Group' / 'Select Category' in px.
   */
  btnWidth?: number;
  /**
   * Defines the tree is readonly and disabled.
   */
  readonly?: boolean;
  /**
   * Defines the group tree to showing disposable groups.
   */
  showDisposableGroups?: boolean;
  /**
   * The asset quantity already used, to validate the chosen group's available quota.
   */
  validateQuota?: { assetQuantity: number };
  /**
   * Defines the tree to be flattened and shows disposable only
   */
  flattenDisposableNode?: boolean;
  /**
   * Defines the group tree to disable excluded keys
   */
  excludedKeys?: string[];
  /**
   * Define wether single selection can be edited or readonly
   * @default true
   */
  singleEditable?: boolean;
  /**
   * Define wether single selection can be reset with close button
   * @default false
   */
  singleResetable?: boolean;
  /**
   * Show all selected node on button render
   *
   * @default false
   */
  fetchTreeOnButtonRender?: boolean;
  /**
   * Disable level 2 (All > Level 1 > Level 2)
   */
  disableSubChildren?: boolean;
  /**
   * 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 ButtonSelectTreeEmits = {
  'update:keys': [keys: KeysModelValue, isAllSelected?: boolean];
  'update:selectedNode': [node: TreeNode | undefined];
  'update:selectedNodes': [nodes: TreeNode[]];
  'dialogShown': [];
  'dialogHidden': [];
  'reset': [];
};

/**
 * **TSVue v2 - ButtonSelectTree**
 *
 * _ButtonSelectTree handles select tree dialog and field validaion._
 *
 * --- ---
 * ![TSVue](https://ik.imagekit.io/kurniadev/TS-HEAD-BLACK.png)
 *
 * @group Component
 */
declare class ButtonSelectTree extends ClassComponent<ButtonSelectTreeProps> {
  dialogTreeKey: Ref<number>;
}

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

export default ButtonSelectTree;
