import { Meta } from "@storybook/react";
import { MultiSelectTreeProps } from "./MultiSelectTreeProps";
import MultiSelectTree from "./MultiSelectTree";

import {
  MultiSelectTreeChangeEvent,
  MultiSelectTreeExpandEvent,
  getMultiSelectTreeValue,
} from "@progress/kendo-react-dropdowns";
import {
  processMultiSelectTreeData,
  expandedState,
} from "./mockData/multiselecttree-data-operations";
import { data } from "../DropDownTree/mockData/tree-data";
import React from "react";

const dataItemKey = "id";
const checkField = "checkField";
const checkIndeterminateField = "checkIndeterminateField";
const subItemsField = "items";
const expandField = "expanded";
const textField = "text";

const fields = {
  dataItemKey,
  checkField,
  checkIndeterminateField,
  expandField,
  subItemsField,
};

export default {
  title: "Design System/Dropdowns/MultiSelectTree",
  component: MultiSelectTree,
  tags: ["autodocs"],
  parameters: {
    docs: {
      description: {
        component:
          'The KendoReact MultiSelectTree is a form component that lets you choose multiple predefined values from a hierarchical list and is a richer version of the select element. Supports filtering, custom rendering, keyboard navigation, expand and collapse of the hierarchical data items. \n\n```javascript\nimport { MultiSelectTree } from "@renault-ui-library"\n```',
      },
    },
  },
  argTypes: {
    dataTestId: {
      control: { type: "text" },
      description: "Specifies the data-test-id attribute for testing purposes.",
    },
    accessKey: {
      control: { type: "text" },
      description: "Specifies the accessKey of the MultiSelectTree.",
    },
    adaptive: {
      control: { type: "boolean" },
      description:
        "Providing different rendering of the popup element based on the screen dimensions.",
    },
    adaptiveTitle: {
      control: { type: "text" },
      description:
        "Specifies the text that is rendered as title in the adaptive popup.",
    },
    ariaDescribedBy: {
      control: { type: "text" },
      description:
        "Identifies the element(s) which will describe the component, similar to HTML aria-describedby attribute.",
    },
    ariaLabelledBy: {
      control: { type: "text" },
      description: "Identifies the element(s) which will label the component.",
    },
    checkField: {
      control: { type: "text" },
      description:
        "Specifies the name of the field which will provide a Boolean representation of the checked state of the item.",
    },
    checkIndeterminateField: {
      control: { type: "text" },
      description:
        "Specifies the name of the field which will provide a Boolean representation of the checked indeterminate state of the item.",
    },
    className: {
      control: { type: "text" },
      description: "Sets additional classes to the MultiSelectTree.",
    },
    data: {
      control: { type: "object" },
      description: "Sets the data of the MultiSelectTree.",
    },
    dataItemKey: {
      control: { type: "text" },
      description:
        "Sets the key for comparing the data items of the MultiSelectTree.",
    },
    dir: {
      control: { type: "text" },
      description: "Represents the dir HTML attribute.",
    },
    disabled: {
      control: { type: "boolean" },
      description: "Sets the disabled state of the MultiSelectTree.",
    },
    expandField: {
      control: { type: "text" },
      description:
        "Specifies the name of the field which will provide a Boolean representation of the expanded state of the item.",
    },
    fillMode: {
      control: {
        type: "select",
        options: ["null", "flat", "outline", "solid"],
      },
      description: "Configures the fillMode of the MultiSelectTree.",
    },
    filter: {
      control: { type: "text" },
      description: "Sets the value of filtering input.",
    },
    filterable: {
      control: { type: "boolean" },
      description:
        "Enables the filtering functionality of the MultiSelectTree.",
    },
    id: {
      control: { type: "text" },
      description: "Specifies the id of the component.",
    },
    item: {
      control: { type: "object" },
      description:
        "Defines the component that will be used for rendering each of the MultiSelectTree items.",
    },
    label: {
      control: { type: "text" },
      description: "Renders a floating label for the MultiSelectTree.",
    },
    listNoData: {
      control: { type: "object" },
      description:
        "Defines the component that will be rendered in the MultiSelectTree popup when no data is available.",
    },
    loading: {
      control: { type: "boolean" },
      description: "Sets the loading state of the MultiSelectTree.",
    },
    name: {
      control: { type: "text" },
      description: "Specifies the name property of the input DOM element.",
    },
    opened: {
      control: { type: "boolean" },
      description: "Sets the opened state of the MultiSelectTree.",
    },
    placeholder: {
      control: { type: "text" },
      description:
        "The hint that is displayed when the MultiSelectTree is empty.",
    },
    popupSettings: {
      control: { type: "object" },
      description: "Configures the popup of the MultiSelectTree.",
    },
    required: {
      control: { type: "boolean" },
      description: "Specifies if null is a valid value for the component.",
    },
    rounded: {
      control: {
        type: "select",
        options: ["null", "small", "medium", "full", "large"],
      },
      description: "Configures the roundness of the MultiSelectTree.",
    },
    size: {
      control: {
        type: "select",
        options: ["null", "small", "medium", "large"],
      },
      description: "Configures the size of the MultiSelectTree.",
    },
    style: {
      control: { type: "object" },
      description: "The styles that are applied to the MultiSelectTree.",
    },
    subItemsField: {
      control: { type: "text" },
      description:
        "Specifies the name of the field which will provide an array representation of the item subitems.",
    },
    tabIndex: {
      control: { type: "number" },
      description: "Specifies the tabIndex of the MultiSelectTree.",
    },
    tag: {
      control: { type: "object" },
      description:
        "Defines the component that will be used for rendering each of the MultiSelectTree tags.",
    },
    tags: {
      control: { type: "object" },
      description: "Sets the tags of the MultiSelect.",
    },
    textField: {
      control: { type: "text" },
      description: "Sets the data item field that represents the item text.",
    },
    valid: {
      control: { type: "boolean" },
      description: "Overrides the validity state of the component.",
    },
    validationMessage: {
      control: { type: "text" },
      description: "Controls the form error message of the component.",
    },
    validityStyles: {
      control: { type: "boolean" },
      description:
        "If set to false, no visual representation of the invalid state of the component will be applied.",
    },
    value: {
      control: { type: "object" },
      description: "Sets the value of the MultiSelectTree.",
    },
    onBlur: {
      control: { type: "function" },
      description: "Fires each time the MultiSelectTree gets blurred.",
    },
    onCancel: {
      control: { type: "function" },
      description:
        "Fires each time the popup of the MultiSelectTree is about to cancel in (adaptive mode).",
    },
    onChange: {
      control: { type: "function" },
      description:
        "Fires each time the value of the MultiSelectTree is about to change.",
    },
    onClose: {
      control: { type: "function" },
      description:
        "Fires each time the popup of the MultiSelectTree is about to close.",
    },
    onExpandChange: {
      control: { type: "function" },
      description:
        "Fires when the expanding or collapsing of an item is requested.",
    },
    onFilterChange: {
      control: { type: "function" },
      description: "Fires each time the user types in the filter input.",
    },
    onFocus: {
      control: { type: "function" },
      description: "Fires each time the user focuses the MultiSelectTree.",
    },
    onOpen: {
      control: { type: "function" },
      description:
        "Fires each time the popup of the MultiSelectTree is about to open.",
    },
    valueMap: {
      control: { type: "function" },
      description:
        "Represents a callback function, which returns the value for submitting.",
    },
  },
} as Meta;

export const Default = (args: MultiSelectTreeProps): JSX.Element => {
  const [value, setValue] = React.useState<any[]>([]);
  const [expanded, setExpanded] = React.useState([data[0][dataItemKey]]);

  const onChange = (event: MultiSelectTreeChangeEvent) =>
    setValue(getMultiSelectTreeValue(data, { ...fields, ...event, value }));
  const onExpandChange = React.useCallback(
    (event: MultiSelectTreeExpandEvent) =>
      setExpanded(expandedState(event.item, dataItemKey, expanded) as number[]),

    [expanded]
  );

  const treeData = React.useMemo(
    () => processMultiSelectTreeData(data, { expanded, value, ...fields }),
    [expanded, value]
  );

  return (
    <MultiSelectTree
      style={args.style}
      data={treeData}
      value={value}
      onChange={onChange}
      placeholder={args.placeholder}
      textField={textField}
      dataItemKey={dataItemKey}
      checkField={checkField}
      checkIndeterminateField={checkIndeterminateField}
      subItemsField={subItemsField}
      expandField={expandField}
      onExpandChange={onExpandChange}
      label={args.label}
    />
  );
};

Default.args = {
  dataTestId: "multiselecttree-data-testid",
  style: { width: 300 },
  placeholder: "Please select ...",
  label: "Category",
  fillMode: "solid",
  rounded: "medium",
  size: "large",
};
