import { useState } from 'react';
import { action } from '@storybook/addon-actions';
import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs';
import { OptionTileGroup } from './OptionTileGroup';
import { Heading } from '../Heading/Heading';
import { Box } from '../Box/Box';

<Meta
  title="Components/OptionTileGroup/Overview"
  component={OptionTileGroup}
  parameters={{
    controls: { hideNoControlsWarning: true },
  }}
/>

# OptionTileGroup

Use a OptionTileGroup when a user is required to select one of five or fewer options. It is ideal for this scenario because the options are displayed without having to interact.
If there are more than five options, use the [SelectInput](?path=/docs/components-selectinput-overview--default-story) instead.

<Canvas isExpanded>
  <Story name="Default">
    {() => {
      const [value, setValue] = useState('chocolate');
      const options = [
        {
          id: 'chocolate_default',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_default',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_default',
          value: 'vanilla',
          label: 'Vanilla',
        },
      ];
      return (
        <OptionTileGroup
          name="default"
          value={value}
          onChange={event => setValue(event.target.value)}
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

## Props

<ArgsTable of={OptionTileGroup} />

## MultiSelect

When a user needs to select more than one element, the underlying inputs will be checkboxes. With the `value` option
now being an array of values.

<Canvas isExpanded>
  <Story name="MultiSelect">
    {() => {
      const [value, setValue] = useState([]);
      const handleSetValue = event => {
        const selectedValue = event.target.value;
        if (value.includes(selectedValue)) {
          setValue([...value].filter(v => v !== selectedValue));
        } else {
          setValue([...value, selectedValue]);
        }
      };
      const options = [
        {
          id: 'chocolate_multi',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_multi',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_multi',
          value: 'vanilla',
          label: 'Vanilla',
        },
      ];
      return (
        <OptionTileGroup
          name="multi"
          value={value}
          onChange={handleSetValue}
          options={options}
          isMulti
        />
      );
    }}
  </Story>
</Canvas>

## Hidden Input

You can render tiles without a radio/checkbox. Note that the input elements are still underlying the component, but this will limit the visual indication
to the selected states on the tile itself. This is likely best when paired with custom content on the tile.

<Canvas isExpanded>
  <Story name="Hidden Input">
    {() => {
      const [value, setValue] = useState('chocolate');
      const options = [
        {
          id: 'chocolate_hidden',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_hidden',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_hidden',
          value: 'vanilla',
          label: 'Vanilla',
        },
      ];
      return (
        <OptionTileGroup
          name="hidden"
          value={value}
          onChange={event => setValue(event.target.value)}
          options={options}
          hideInput
        />
      );
    }}
  </Story>
</Canvas>

## Direction

Set the direction (flex) of the tiles. It can be one of `row` or `column` but will also take a `ResponsiveProp` object with either of these values. (see example).

<Canvas isExpanded>
  <Story name="Direction">
    {() => {
      const [valueVertical, setValueVertical] = useState('chocolate');
      const optionsVertical = [
        {
          id: 'chocolate_direction',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_direction',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_direction',
          value: 'vanilla',
          label: 'Vanilla',
        },
      ];
      return (
        <>
          <p className="m-bottom-md font-size-lg font-weight-bold">
            Responsive Direction (change your viewport to see it in action)
          </p>
          <OptionTileGroup
            name="directionVertical"
            value={valueVertical}
            onChange={event => setValueVertical(event.target.value)}
            options={optionsVertical}
            direction={{ base: 'column', tablet: 'row' }}
          />
        </>
      );
    }}
  </Story>
</Canvas>

## Title and Description

Acting as the fieldset legend.

<Canvas isExpanded>
  <Story name="Title and Description">
    {() => {
      const [value, setValue] = useState('chocolate');
      const options = [
        {
          id: 'chocolate_title',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_title',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_title',
          value: 'vanilla',
          label: 'Vanilla',
        },
      ];
      return (
        <OptionTileGroup
          name="titleAndDescription"
          title="Ice cream flavors"
          description="Only if you eat all your dinner"
          value={value}
          onChange={event => setValue(event.target.value)}
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

## Required

Sets the required and aria-required attributes on the options in the group. To avoid confusion as to whether a radio button group is required or not, authors are encouraged to specify the attribute on all the radio buttons in a group. We recommend to avoid having radio button groups that do not have any initially checked controls in the first place, because this is a state that the user cannot return to.

<Canvas isExpanded>
  <Story name="Required">
    {() => {
      const [value, setValue] = useState('chocolate');
      const options = [
        {
          id: 'chocolate_required',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_required',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_required',
          value: 'vanilla',
          label: 'Vanilla',
        },
      ];
      return (
        <OptionTileGroup
          name="required"
          title="Ice cream flavors"
          isRequired
          value={value}
          onChange={event => setValue(event.target.value)}
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

## Disabling Options

A `disabled` attribute can be passed inside the `Option` object to disable any particular option.

<Canvas isExpanded>
  <Story name="Disabled Options">
    {() => {
      const [value, setValue] = useState();
      const [valueMulti, setValueMulti] = useState([]);
      const handleSetValueMulti = event => {
        const selectedValue = event.target.value;
        if (valueMulti.includes(selectedValue)) {
          setValueMulti([...valueMulti].filter(v => v !== selectedValue));
        } else {
          setValueMulti([...valueMulti, selectedValue]);
        }
      };
      const options = [
        {
          id: 'chocolate_disabled',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_disabled',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_disabled',
          value: 'vanilla',
          label: 'Vanilla',
          disabled: true,
        },
      ];
      const optionsMulti = [
        {
          id: 'chocolate_disabled_multi',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_disabled_multi',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_disabled_multi',
          value: 'vanilla',
          label: 'Vanilla',
          disabled: true,
        },
      ];
      return (
        <>
          <OptionTileGroup
            name="disabled"
            value={value}
            onChange={event => setValue(event.target.value)}
            options={options}
            margin="0 0 lg 0"
          />
          <OptionTileGroup
            name="disabledMulti"
            value={valueMulti}
            onChange={handleSetValueMulti}
            options={optionsMulti}
            isMulti
          />
        </>
      );
    }}
  </Story>
</Canvas>

## Error

Pass an error (or boolean with no message) to notify a user when something isn't right. Likely paired with `isRequired` in most cases.

<Canvas isExpanded>
  <Story name="Error">
    {() => {
      const [value, setValue] = useState([]);
      const options = [
        {
          id: 'chocolate_error',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_error',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_error',
          value: 'vanilla',
          label: 'Vanilla',
          disabled: true,
        },
      ];
      return (
        <OptionTileGroup
          name="required"
          title="Ice cream flavors"
          description="Only if you eat all your dinner"
          isRequired
          value={value}
          onChange={event => setValue(event.target.value)}
          options={options}
          error="You should really select an ice cream flavor!"
        />
      );
    }}
  </Story>
</Canvas>

Pass an `error` to an individual option to indicate that something about that specific option is invalid.

<Canvas isExpanded>
  <Story name="Single Error">
    {() => {
      const [value, setValue] = useState('strawberry');
      const options = [
        {
          id: 'chocolate_error2',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_error2',
          value: 'strawberry',
          label: 'Strawberry',
          error: 'single error',
        },
        {
          id: 'vanilla_error2',
          value: 'vanilla',
          label: 'Vanilla',
        },
      ];
      return (
        <OptionTileGroup
          name="required"
          title="Ice cream flavors"
          description="Only if you eat all your dinner"
          isRequired
          value={value}
          onChange={event => setValue(event.target.value)}
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

## Full Width

The OptionsTile component has fullWidth (100%) enabled by default but it can be disabled if need be.

<Canvas isExpanded>
  <Story name="Not Full Width">
    {() => {
      const [valueHorizontal, setValueHorizontal] = useState([]);
      const [valueVertical, setValueVertical] = useState([]);
      const optionsVertical = [
        {
          id: 'chocolate_fullwidth_vertical',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_fullwidth_vertical',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_fullwidth_vertical',
          value: 'vanilla',
          label: 'Vanilla',
        },
      ];
      const optionsHorizontal = [
        {
          id: 'chocolate_fullwidth_horizontal',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry_fullwidth_horizontal',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla_fullwidth_horizontal',
          value: 'vanilla',
          label: 'Vanilla',
        },
      ];
      return (
        <>
          <p className="m-bottom-md font-size-lg font-weight-bold">Vertical</p>
          <OptionTileGroup
            name="fullWidthVertical"
            value={valueVertical}
            onChange={event => setValueVertical(event.target.value)}
            options={optionsVertical}
            direction="column"
            isFullWidth={false}
          />
          <p className="m-v-md font-size-lg font-weight-bold">Horizontal</p>
          <OptionTileGroup
            name="fullWidthHorizontal"
            value={valueHorizontal}
            onChange={event => setValueHorizontal(event.target.value)}
            options={optionsHorizontal}
            direction="row"
            isFullWidth={false}
          />
        </>
      );
    }}
  </Story>
</Canvas>

## Custom Content

The tiles can render custom content with a `render` function passed in the option object.

<Canvas isExpanded>
  <Story name="Custom Content">
    {() => {
      const [value, setValue] = useState([]);
      const options = [
        {
          id: 'chocolate_custom',
          value: 'chocolate',
          label: 'Chocolate',
          render: option => (
            <Box>
              <Heading as="h3" size="lg" className="m-bottom-sm">
                {option.label}
              </Heading>
              <Box
                as="img"
                maxWidth="120px"
                radius="md"
                borderWidth="md"
                borderColor="separator"
                src="https://www.thespruceeats.com/thmb/BYOHKcXhja-ez7Fr9obgBrDHJ1Y=/3064x2042/filters:fill(auto,1)/easy-chocolate-ice-cream-recipe-1945798-hero-01-45d9f26a0aaf4c1dba38d7e0a2ab51e2.jpg"
              />
            </Box>
          ),
        },
        {
          id: 'strawberry_custom',
          value: 'strawberry',
          label: 'Strawberry',
          render: option => (
            <Box>
              <Heading as="h3" size="lg" className="m-bottom-sm">
                {option.label}
              </Heading>
              <Box
                as="img"
                maxWidth="120px"
                radius="md"
                borderWidth="md"
                borderColor="separator"
                src="https://www.seriouseats.com/thmb/AVrcpDEKKinSsmgcHvMNxBVCdXc=/1500x844/smart/filters:no_upscale()/__opt__aboutcom__coeus__resources__content_migration__serious_eats__seriouseats.com__recipes__images__2015__07__20150706-strawberry-ice-cream-vicky-wasik-4-f3453966ec94404aaf44da724aef978b.jpg"
              />
            </Box>
          ),
        },
        {
          id: 'vanilla_custom',
          value: 'vanilla',
          label: 'Vanilla',
          render: option => (
            <Box>
              <Heading as="h3" size="lg" className="m-bottom-sm">
                {option.label}
              </Heading>
              <Box
                as="img"
                maxWidth="120px"
                radius="md"
                borderWidth="md"
                borderColor="separator"
                src="data:image/jpeg;base64, "
              />
            </Box>
          ),
        },
      ];
      return (
        <OptionTileGroup
          name="customContent"
          value={value}
          onChange={event => setValue(event.target.value)}
          options={options}
          direction={{ base: 'column', tablet: 'row' }}
        />
      );
    }}
  </Story>
</Canvas>
