
import type { *, OrTreeMenu } from "./lib/index.d.ts";
import type { OrTreeGroup } from "./lib/or-tree-group.d.ts";
import type { OrTreeNode } from "./lib/or-tree-node.d.ts";

/**
 * This type can be used to create scoped tags for your components.
 *
 * Usage:
 *
 * ```ts
 * import type { ScopedElements } from "path/to/library/jsx-integration";
 *
 * declare module "my-library" {
 *   namespace JSX {
 *     interface IntrinsicElements
 *       extends ScopedElements<'test-', ''> {}
 *   }
 * }
 * ```
 *
 * @deprecated Runtime scoped elements result in duplicate types and can confusing for developers. It is recommended to use the `prefix` and `suffix` options to generate new types instead.
 */
export type ScopedElements<
  Prefix extends string = "",
  Suffix extends string = ""
> = {
  [Key in keyof CustomElements as `${Prefix}${Key}${Suffix}`]: CustomElements[Key];
};

type BaseProps<T extends HTMLElement> = {

  /** Content added between the opening and closing tags of the element */
  children?: any;
  /** Used for declaratively styling one or more elements using CSS (Cascading Stylesheets) */
  class?: string;
  /** Used for declaratively styling one or more elements using CSS (Cascading Stylesheets) */
  className?: string;
  /** Takes an object where the key is the class name(s) and the value is a boolean expression. When true, the class is applied, and when false, it is removed. */
  classList?: Record<string, boolean | undefined>;
  /** Specifies the text direction of the element. */
  dir?: "ltr" | "rtl";
  /** Contains a space-separated list of the part names of the element that should be exposed on the host element. */
  exportparts?: string;
  /** For <label> and <output>, lets you associate the label with some control. */
  htmlFor?: string;
  /** Specifies whether the element should be hidden. */
  hidden?: boolean | string;
  /** A unique identifier for the element. */
  id?: string;
  /** Keys tell React which array item each component corresponds to */
  key?: string | number;
  /** Specifies the language of the element. */
  lang?: string;
  /** Contains a space-separated list of the part names of the element. Part names allows CSS to select and style specific elements in a shadow tree via the ::part pseudo-element. */
  part?: string;
  /** Use the ref attribute with a variable to assign a DOM element to the variable once the element is rendered. */
  ref?: T | ((e: T) => void);
  /** Adds a reference for a custom element slot */
  slot?: string;
  /** Prop for setting inline styles */
  style?: Record<string, string | number>;
  /** Overrides the default Tab button behavior. Avoid using values other than -1 and 0. */
  tabIndex?: number;
  /** Specifies the tooltip text for the element. */
  title?: string;
  /** Passing 'no' excludes the element content from being translated. */
  translate?: "yes" | "no";
  /** The popover global attribute is used to designate an element as a popover element. */
  popover?: "auto" | "hint" | "manual";
  /** Turns an element element into a popover control button; takes the ID of the popover element to control as its value. */
  popovertarget?: "top" | "bottom" | "left" | "right" | "auto";
  /** Specifies the action to be performed on a popover element being controlled by a control element. */
  popovertargetaction?: "show" | "hide" | "toggle";

} ;

type BaseEvents = {


};



export type OrTreeMenuProps = {
  /** List of node items in the menu.
Uses the TreeNode format for rendering the OrTreeNode elements. */
  "nodes"?: OrTreeMenu['nodes'];
  /** Changes the allowed selection method within the tree.
Common options are `LEAF`, `SINGLE` and `MULTI`. */
  "selection"?: OrTreeMenu['selection'];
  /** Disables and enables dragging of nodes into groups. */
  "draggable"?: OrTreeMenu['draggable'];
  /** Removes the header from the tree menu. */
  "no-header"?: OrTreeMenu['noHeader'];
  /** Removes the header from the tree menu. */
  "noHeader"?: OrTreeMenu['noHeader'];
  /** Adjusts the title in the menu header. */
  "menu-title"?: OrTreeMenu['menuTitle'];
  /** Adjusts the title in the menu header. */
  "menuTitle"?: OrTreeMenu['menuTitle'];
  /** List of options available to sort the object with */
  "sort-options"?: OrTreeMenu['sortOptions'];
  /** List of options available to sort the object with */
  "sortOptions"?: OrTreeMenu['sortOptions'];
  /** Represents the selected sorting option */
  "sort-by"?: OrTreeMenu['sortBy'];
  /** Represents the selected sorting option */
  "sortBy"?: OrTreeMenu['sortBy'];
  /** Automatically prioritizes the groups, and positions these on top. */
  "group-first"?: OrTreeMenu['groupFirst'];
  /** Automatically prioritizes the groups, and positions these on top. */
  "groupFirst"?: OrTreeMenu['groupFirst'];

  /**  */
  "onnodes"?: (e: CustomEvent<OrTreeDragEvent>) => void;
  /**  */
  "onundefined"?: (e: CustomEvent<OrTreeSelectEvent>) => void;
  /** Triggers upon selecting a node, and dispatches a list of the nodes selected. */
  "onor-tree-select"?: (e: CustomEvent<OrTreeSelectEvent>) => void;
  /** Triggers upon dragging a node to a new group, and dispatches a list of dragged nodes, the group node, and the updated list of all nodes. */
  "onor-tree-drag"?: (e: CustomEvent<OrTreeDragEvent>) => void;
}


export type OrTreeGroupProps = {
  /** Determines the visibility of child nodes.
Setting this to `false` hides them, and acts as a 'collapsed' state. */
  "expanded"?: OrTreeGroup['expanded'];
  /** Only allows child nodes to be selected, making the expander (parent node) readonly.
If this is set to false, only the chevron icon can be used to collapse/expand the list. */
  "leaf"?: OrTreeGroup['leaf'];
  /** Makes the group readonly */
  "readonly"?: OrTreeGroup['readonly'];


}


export type OrTreeNodeProps = {
  /** HTML attribute that only applies CSS, showing this node cannot be interacted with. */
  "readonly"?: OrTreeNode['readonly'];
  /** HTML attribute that only applies CSS, marking the node as 'selected'. */
  "selected"?: OrTreeNode['selected'];


}

  export type CustomElements = {


  /**
     * A component for displaying a hierarchical, tree-like structure of elements.
 * Common use cases are visualizing parent-child relationships, or for grouping elements together.
 * 
 * ## Attributes & Properties
 * 
 * Component attributes and properties that can be applied to the element or by using JavaScript.
 * 
 * - `nodes`: List of node items in the menu.
 * Uses the TreeNode format for rendering the OrTreeNode elements. 
 * - `selection`: Changes the allowed selection method within the tree.
 * Common options are `LEAF`, `SINGLE` and `MULTI`. 
 * - `draggable`: Disables and enables dragging of nodes into groups. 
 * - `no-header`/`noHeader`: Removes the header from the tree menu. 
 * - `menu-title`/`menuTitle`: Adjusts the title in the menu header. 
 * - `sort-options`/`sortOptions`: List of options available to sort the object with 
 * - `sort-by`/`sortBy`: Represents the selected sorting option 
 * - `group-first`/`groupFirst`: Automatically prioritizes the groups, and positions these on top. 
 * 
 * ## Events
 * 
 * Events that will be emitted by the component.
 * 
 * - `nodes`: undefined
 * - `undefined`: undefined
 * - `or-tree-select`: Triggers upon selecting a node, and dispatches a list of the nodes selected.
 * - `or-tree-drag`: Triggers upon dragging a node to a new group, and dispatches a list of dragged nodes, the group node, and the updated list of all nodes.
 * 
 * ## Methods
 * 
 * Methods that can be called to access component functionality.
 * 
 * - `moveNodesToGroup(nodesToMove: TreeNode[], groupNode?: TreeNode) => void`: Function that moves an array of TreeNode into another TreeNode, by adding them to their children.
 * The function takes care of removing the nodes from the former group, and makes sure no duplicates end up in the list.
 * - `deselectAllNodes() => void`: Public function that deselects all tree nodes.
 * - `expandGroup(groupId: string) => void`: Programmatically finds a group by its ID and sets it to be expanded.
 * This is called by the parent component after a new node is added to a tree group.
  */
    "or-tree-menu": Partial<OrTreeMenuProps & BaseProps<OrTreeMenu> & BaseEvents>;


  /**
     * 
 * 
 * ## Attributes & Properties
 * 
 * Component attributes and properties that can be applied to the element or by using JavaScript.
 * 
 * - `expanded`: Determines the visibility of child nodes.
 * Setting this to `false` hides them, and acts as a 'collapsed' state. 
 * - `leaf`: Only allows child nodes to be selected, making the expander (parent node) readonly.
 * If this is set to false, only the chevron icon can be used to collapse/expand the list. 
 * - `readonly`: Makes the group readonly 
 * 
 * ## Slots
 * 
 * Areas where markup can be added to the component.
 * 
 * - `(default)`: Default slot for child nodes within the group
 * - `parent`: Slot for inserting a parent node
 * 
 * ## Methods
 * 
 * Methods that can be called to access component functionality.
 * 
 * - `select() => void`: Selects the group (parent) node.
 * - `selectAll() => void`: Selects the group node itself, and all children nodes within that group.
 * - `deselect() => void`: Deselects the group (parent) node.
 * - `deselectAll() => void`: Deselects the group node itself, and all children nodes within that group.
 * - `getGroupNode() => OrTreeNode | undefined`: Returns the group (parent) node (OrTreeNode) using a query selector.
 * - `getChildNodes() => OrTreeNode[]`: Returns a list of all children nodes (OrTreeNode) within the group, using a query selector.
 * 
 * ## CSS Parts
 * 
 * Custom selectors for styling elements within the component.
 * 
 * - `chevron`: The chevron icon element for expanding/collapsing the group.
  */
    "or-tree-group": Partial<OrTreeGroupProps & BaseProps<OrTreeGroup> & BaseEvents>;


  /**
     * 
 * 
 * ## Attributes & Properties
 * 
 * Component attributes and properties that can be applied to the element or by using JavaScript.
 * 
 * - `readonly`: HTML attribute that only applies CSS, showing this node cannot be interacted with. 
 * - `selected`: HTML attribute that only applies CSS, marking the node as 'selected'. 
 * 
 * ## Slots
 * 
 * Areas where markup can be added to the component.
 * 
 * - `prefix`: Appends elements to the left hand side of the node, commonly used for icons.
 * - `(default)`: Default slot for the main content, commonly used for text.
 * - `suffix`: Appends elements to the right hand side of the node.
 * 
 * ## CSS Custom Properties
 * 
 * CSS variables available for styling the component.
 * 
 * - `--or-tree-node-height`: Controls the height of the node (default: `undefined`)
 * - `--or-tree-node-indent`: Controls the left padding of the node (default: `undefined`)
 * - `--or-tree-node-background`: Sets the default background (default: `undefined`)
 * - `--or-tree-node-background--hovered`: Sets the background while hovering (default: `undefined`)
 * - `--or-tree-node-background--selected`: Sets the background when selected (default: `undefined`)
 * - `--or-tree-node-color--selected`: Sets the primary color of the node when selected (default: `undefined`)
  */
    "or-tree-node": Partial<OrTreeNodeProps & BaseProps<OrTreeNode> & BaseEvents>;
  }

export type CustomCssProperties = {
  /** Controls the height of the node */
  "--or-tree-node-height"?: string;
  /** Controls the left padding of the node */
  "--or-tree-node-indent"?: string;
  /** Sets the default background */
  "--or-tree-node-background"?: string;
  /** Sets the background while hovering */
  "--or-tree-node-background--hovered"?: string;
  /** Sets the background when selected */
  "--or-tree-node-background--selected"?: string;
  /** Sets the primary color of the node when selected */
  "--or-tree-node-color--selected"?: string;
}


declare module 'react' {
  namespace JSX {
    interface IntrinsicElements extends CustomElements {}
  }
  export interface CSSProperties extends CustomCssProperties {}
}

declare module 'preact' {
  namespace JSX {
    interface IntrinsicElements extends CustomElements {}
  }
  export interface CSSProperties extends CustomCssProperties {}
}

declare module '@builder.io/qwik' {
  namespace JSX {
    interface IntrinsicElements extends CustomElements {}
  }
  export interface CSSProperties extends CustomCssProperties {}
}

declare module '@stencil/core' {
  namespace JSX {
    interface IntrinsicElements extends CustomElements {}
  }
  export interface CSSProperties extends CustomCssProperties {}
}

declare module 'hono/jsx' {
  namespace JSX {
    interface IntrinsicElements extends CustomElements {}
  }
  export interface CSSProperties extends CustomCssProperties {}
}

declare module 'react-native' {
  namespace JSX {
    interface IntrinsicElements extends CustomElements {}
  }
  export interface CSSProperties extends CustomCssProperties {}
}

declare global {
  namespace JSX {
    interface IntrinsicElements extends CustomElements {}
  }
  export interface CSSProperties extends CustomCssProperties {}
}
