import { useState, useReducer } from "react";
import { Meta, Preview, Props, Story } from "@storybook/addon-docs/blocks";
import { Tag, TAG_VARIANT } from "./Tag";
import { ICON_TYPE } from "../Icon";
import { Stack } from "../Stack";
import { ORIENTATION } from "../../types";
import { EnumTable } from "../../storybook-components/EnumTable";

<Meta title="Components/Data/Tag" component={Tag} />

# Tag

```jsx
import { Tag } from "@aptible/arrow-ds";
```

<Preview>
  <Story name="Tag">
    <Tag>Tag</Tag>
  </Story>
</Preview>

## `Tag` Custom Props

These are the custom props that extend [`BoxProps`](/?path=/docs/components-box--box#all-props).

<Props of={Tag} />
<EnumTable enums={{ TAG_VARIANT, ICON_TYPE }} />

# Tag.Group

The `Tag.Group` component properly spaces a group of `Tag` components. Tags in the group should automatically wrap onto new lines like text and be left-aligned.

`Tag.Group` uses [`BoxProps`](/?path=/docs/components-box--box#all-props) and does not have any custom props.

## `Tag` Demos

### Variants

<Preview>
  <Story name="VariantPrimary">
    <Tag variant={TAG_VARIANT.PRIMARY}>Primary</Tag>
  </Story>
  <Story name="VariantSecondary">
    <Tag>Secondary</Tag>
  </Story>
</Preview>

### Filled

Use the filled in appearance to give the `Tag` more emphasis or visual weight

<Preview>
  <Story name="FilledPrimary">
    <Tag filled variant={TAG_VARIANT.PRIMARY}>
      Primary
    </Tag>
  </Story>
  <Story name="FilledSecondary">
    <Tag filled>Secondary</Tag>
  </Story>
</Preview>

### With Icon

<Preview>
  <Story name="WithIconPrimary">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Tag icon={ICON_TYPE.POO_STORM} variant={TAG_VARIANT.PRIMARY}>
        Primary
      </Tag>
      <Tag icon={ICON_TYPE.POO_STORM} filled variant={TAG_VARIANT.PRIMARY}>
        Primary
      </Tag>
    </Stack>
  </Story>
  <Story name="WithIconSecondary">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Tag icon={ICON_TYPE.POO_STORM}>Secondary</Tag>
      <Tag icon={ICON_TYPE.POO_STORM} filled>
        Secondary
      </Tag>
    </Stack>
  </Story>
</Preview>

### Icon Only

<Preview>
  <Story name="IconOnlyPrimary">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Tag icon={ICON_TYPE.POO_STORM} variant={TAG_VARIANT.PRIMARY} />
      <Tag icon={ICON_TYPE.POO_STORM} filled variant={TAG_VARIANT.PRIMARY} />
    </Stack>
  </Story>
  <Story name="IconOnlySecondary">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Tag icon={ICON_TYPE.POO_STORM} />
      <Tag icon={ICON_TYPE.POO_STORM} filled />
    </Stack>
  </Story>
</Preview>

### As a clickable element

Tags can be rendered as other elements using the `as` prop. If the element is clickable, add the `clickable` prop to add hover and focused styles.

<Preview>
  <Story name="AsLink">
    <Tag
      clickable
      as="a"
      href="http://google.com"
      variant={TAG_VARIANT.PRIMARY}
    >
      Link - Primary
    </Tag>
  </Story>
  <Story name="AsButton">
    <Tag clickable as="button" onClick={() => console.log("clicked")}>
      Button - Secondary
    </Tag>
  </Story>
  <Story name="AsButtonFilledPrimary">
    <Tag
      variant={TAG_VARIANT.PRIMARY}
      clickable
      as="button"
      onClick={() => console.log("clicked")}
      filled
    >
      Button - Primary
    </Tag>
  </Story>
  <Story name="AsButtonFilledSecondary">
    <Tag clickable as="button" onClick={() => console.log("clicked")} filled>
      Button - Secondary
    </Tag>
  </Story>
</Preview>

### Toggleable

If a tag is used to show an "on/off" or "selected/deselected" state, add the `toggleable` prop in combination with the `filled` prop to get the correct styles.

<Preview>
  <Story name="Toggle">
    {() => {
      const [filled, setFilled] = useState(false);
      return (
        <Tag
          toggleable
          as="button"
          onClick={() => setFilled(!filled)}
          filled={filled}
          variant={TAG_VARIANT.TOGGLE}
        >
          Toggle
        </Tag>
      );
    }}
  </Story>
</Preview>

## `Tag.Group` Demos

### Group of Toggleable Tags

<Preview>
  <Story name="TagGroup variant">
    {() => {
      const tagNames = ["one", "two", "three", "four", "five"];
      const tagGroupStateReducer = (tagGroupState, tagName) => {
        const current = tagGroupState[tagName];
        return { ...tagGroupState, [tagName]: !current };
      };
      const initialTagGroupState = tagNames.reduce((current, tagName) => {
        // eslint-disable-next-line no-param-reassign
        current[tagName] = false;
        return current;
      }, {});
      const [tagGroupState, tagGroupDispatch] = useReducer(
        tagGroupStateReducer,
        initialTagGroupState,
      );
      return (
        <Tag.Group>
          {tagNames.map((tagName) => (
            <Tag
              key={tagName}
              as="button"
              toggleable
              filled={tagGroupState[tagName]}
              onClick={() => tagGroupDispatch(tagName)}
            >
              {tagName}
            </Tag>
          ))}
        </Tag.Group>
      );
    }}
  </Story>
</Preview>
