// @flow
import React, { useState } from 'react';
import randomstring from 'randomstring';
import { remove, concat } from 'lodash';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { withInfo } from '@storybook/addon-info';
import { configDocs } from '../../../../.storybook/config-docs';
import docs from './SELECTOR.mkd';
import { Selector } from './index';
import { SelectorItem } from './selector-item';
import { SelectorButton } from './selector-button';
import { Grid, GridItem } from '../../structures';
import { Box } from '../../../primitives';
import { Text } from '../../typography';
import { SelectorItemWithInput } from './selector-item-with-input';

const ExampleRow = () => (
  <Box stacked="column" spacing={['ph1', 'pt2']}>
    <Text bold spacing="mv0">
      CIBC Everyday Savings Account
    </Text>
    <Text fontSize="f1" spacing="mt1">
      Ending in 1234
    </Text>
  </Box>
);

storiesOf('Core/Forms/Selector/RadioOption', module)
  .addDecorator(withInfo(configDocs(docs, Selector)))
  .add('With Label', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Selector
            name={demoId}
            onChange={action('onChange')}
            label="Choose one"
            stateful
          >
            <SelectorItem
              id="option-one"
              label="First choice"
              value="option-one"
            />
            <SelectorItem
              id="option-two"
              label="Second choice"
              value="option-two"
            />
          </Selector>
        </GridItem>
      </Grid>
    );
  })
  .add('Large', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Selector
            name={demoId}
            onChange={action('onChange')}
            stateful
            size="lg"
          >
            <SelectorItem
              id="option-one"
              label="First choice"
              value="option-one"
            />
            <SelectorItem
              id="option-two"
              label="Second choice"
              value="option-two"
            />
          </Selector>
        </GridItem>
      </Grid>
    );
  })
  .add('Disabled', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Selector name={demoId} onChange={action('onChange')} stateful>
            <SelectorItem
              id="option-one"
              label="First choice"
              value="option-one"
            />
            <SelectorItem
              id="option-two"
              label="Second choice"
              value="option-two"
              disabled
            />
            <SelectorItem
              id="option-three"
              label="Third choice"
              value="option-three"
            />
          </Selector>
        </GridItem>
      </Grid>
    );
  })
  .add('With React Elements as Content', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Selector name={demoId} onChange={action('onChange')} stateful>
            <SelectorItem id="option-one" value="option-one">
              <ExampleRow />
            </SelectorItem>
            <SelectorItem id="option-two" value="option-two">
              <ExampleRow />
            </SelectorItem>
          </Selector>
        </GridItem>
      </Grid>
    );
  })
  .add('With labels, secondaryLabels, and children', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Selector name={demoId} onChange={action('onChange')} stateful>
            <SelectorItem id="option-one" label="One" value={1} />
            <SelectorItem
              id="option-two"
              label="Two"
              secondaryLabel="Secondary"
              value={2}
            />
            <SelectorItem
              id="option-three"
              label="Three"
              secondaryLabel="Secondary label with a very long description"
              value={3}
            />
            <SelectorItem id="option-four" label="Four" value={4}>
              <Box>
                <Text fontSize="f1">
                  I am a child rendered how you would like.
                </Text>
              </Box>
            </SelectorItem>
            <SelectorButton onClick={action('onClick')}>
              Do custom unrelated action
            </SelectorButton>
          </Selector>
        </GridItem>
      </Grid>
    );
  })
  .add('With selector items that have a lot of text', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Selector name={demoId} onChange={action('onChange')} stateful>
            <SelectorItem id="option-one" value="option-one">
              <Box stacked="column" spacing={['ph1', 'pt2']}>
                <Text bold spacing="mv0">
                  A fancy bank name that is quite long
                </Text>
                <Text fontSize="f1" spacing="mt1">
                  fake text fake text fake text fake text fake text fake text
                  fake text fake text fake text fake text fake text
                </Text>
              </Box>
            </SelectorItem>
            <SelectorItem
              id="option-two"
              value="option-two"
              label="fake text fake text fake text fake text fake text fake text
                fake text fake text fake text fake text fake text"
            />
            <SelectorItem id="option-three" value="option-three" label="fake" />
          </Selector>
        </GridItem>
      </Grid>
    );
  })
  .add('with Selector value (stateful)', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Text>
            The component manages the checked state and you get the value
            onChange
          </Text>

          <Selector
            name={demoId}
            onChange={action('onChange')}
            value="option-two"
            stateful
          >
            <SelectorItem
              id="option-one"
              label="First choice"
              value="option-one"
            />
            <SelectorItem
              id="option-two"
              label="Second choice"
              value="option-two"
            />
          </Selector>
        </GridItem>
      </Grid>
    );
  })
  .add('with checked value (default, stateless)', () => {
    const CheckedValuesForRadioDemo = () => {
      const demoId = `selector-demo-${randomstring.generate(2)}`;
      const [selected, setSelected] = useState('vanilla');

      return (
        <Grid>
          <GridItem sm={12} md={6} lg={4}>
            <Text>
              You manage the checked state yourself and you get the selected
              value onChange
            </Text>

            <Selector
              name={demoId}
              onChange={v => {
                setSelected(v);
                action('onChange')(v);
              }}
            >
              <SelectorItem
                id="chocolate"
                label="🍫 Chocolate"
                value="chocolate"
                checked={selected === 'chocolate'}
              />
              <SelectorItem
                id="vanilla"
                label="🍦 Vanilla"
                value="vanilla"
                checked={selected === 'vanilla'}
              />
            </Selector>
          </GridItem>
        </Grid>
      );
    };

    return <CheckedValuesForRadioDemo />;
  })
  .add('with selector with freeform text input', () => {
    const CheckedValuesForRadioDemo = () => {
      const demoId = `selector-demo-${randomstring.generate(2)}`;
      const [selected, setSelected] = useState('vanilla');
      const [inputValue, setInputValue] = useState();
      return (
        <Grid>
          <GridItem sm={12} md={6} lg={4}>
            <Selector
              name={demoId}
              onChange={v => {
                setSelected(v);
                action('onChange')(v);
              }}
            >
              <SelectorItem
                id="vanilla"
                label="🍦 Vanilla"
                value="vanilla"
                checked={selected === 'vanilla'}
              />
              <SelectorItem
                id="ice-cream-chocolate"
                label="🍫 Chocolate"
                value="chocolate"
                checked={selected === 'chocolate'}
              />
              <SelectorItemWithInput
                id="other"
                label="Other (written below)"
                value="other"
                checked={selected === 'other'}
                inputValue={inputValue}
                onInputChange={value => {
                  action('onInputChange');
                  setInputValue(value);
                }}
                inputProps={{
                  placeholder: 'Something delicious',
                }}
              />
            </Selector>
          </GridItem>
        </Grid>
      );
    };

    return <CheckedValuesForRadioDemo />;
  })
  .add('with error on selector with freeform text input', () => {
    const CheckedValuesForRadioDemo = () => {
      const demoId = `selector-demo-${randomstring.generate(2)}`;
      const [selected, setSelected] = useState('vanilla');
      const [inputValue, setInputValue] = useState(
        'Something that is not valid',
      );
      return (
        <Grid>
          <GridItem sm={12} md={6} lg={4}>
            <Selector
              name={demoId}
              onChange={v => {
                setSelected(v);
                action('onChange')(v);
              }}
            >
              <SelectorItem
                id="vanilla"
                label="🍦 Vanilla"
                value="vanilla"
                checked={selected === 'vanilla'}
              />
              <SelectorItem
                id="ice-cream-chocolate"
                label="🍫 Chocolate"
                value="chocolate"
                checked={selected === 'chocolate'}
              />
              <SelectorItemWithInput
                id="other"
                label="Other (written below)"
                value="other"
                checked={selected === 'other'}
                inputValue={inputValue}
                onInputChange={value => {
                  action('onInputChange');
                  setInputValue(value);
                }}
                inputProps={{
                  placeholder: 'Something delicious',
                }}
                inputError="Input value is invalid"
              />
            </Selector>
          </GridItem>
        </Grid>
      );
    };

    return <CheckedValuesForRadioDemo />;
  })
  .add('Small variant (size="sm")', () => {
    const CheckedValuesForCheckboxDemo = () => {
      const demoId = `selector-demo-${randomstring.generate(2)}`;
      const [selected, setSelected] = useState(['chocolate', 'vanilla']);

      return (
        <Grid>
          <GridItem sm={12} md={6} lg={4}>
            <Selector
              name={demoId}
              type="checkbox"
              size="sm"
              onChange={v => {
                if (selected.includes(v)) {
                  const newSelected = remove(selected, item => v !== item);
                  setSelected(newSelected);
                } else {
                  const newSelected = concat(selected, v);
                  setSelected(newSelected);
                }

                action('onChange')(Array.isArray(v) ? v.join(', ') : v);
              }}
            >
              <SelectorItem
                id="chocolate"
                label="Chocolate"
                value="chocolate"
                checked={selected.includes('chocolate')}
              />
              <SelectorItem
                id="vanilla"
                label="Vanilla"
                value="vanilla"
                checked={selected.includes('vanilla')}
              />
              <SelectorItem
                id="strawberry"
                label="Strawberry"
                value="strawberry"
                checked={selected.includes('strawberry')}
              />
            </Selector>
          </GridItem>
        </Grid>
      );
    };

    return <CheckedValuesForCheckboxDemo />;
  });

storiesOf('Core/Forms/Selector/Checkbox', module)
  .add('With Label', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Selector
            name={demoId}
            type="checkbox"
            onChange={v => {
              action('onChange')(Array.isArray(v) ? v.join(', ') : v);
            }}
            label="Choose one"
          >
            <SelectorItem
              id="option-one"
              label="First choice"
              value="option-one"
            />
            <SelectorItem
              id="option-two"
              label="Second choice"
              value="option-two"
            />
          </Selector>
        </GridItem>
      </Grid>
    );
  })
  .add('With React Elements as Content', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Selector
            name={demoId}
            type="checkbox"
            onChange={v => {
              action('onChange')(Array.isArray(v) ? v.join(', ') : v);
            }}
          >
            <SelectorItem id="option-one" value="option-one">
              <ExampleRow />
            </SelectorItem>
            <SelectorItem id="option-two" value="option-two">
              <ExampleRow />
            </SelectorItem>
          </Selector>
        </GridItem>
      </Grid>
    );
  })
  .add('with Selector value (stateful)', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Selector
            name={demoId}
            type="checkbox"
            onChange={v => {
              action('onChange')(Array.isArray(v) ? v.join(', ') : v);
            }}
            value={['vanilla', 'chocolate']}
            stateful
          >
            <SelectorItem
              id="ice-cream-chocolate"
              label="🍫 Chocolate"
              value="chocolate"
            />
            <SelectorItem
              id="ice-cream-vanilla"
              label="🍦 Vanilla"
              value="vanilla"
            />
            <SelectorItem
              id="ice-cream-strawberry"
              label="🍓 Strawberry"
              value="strawberry"
            />
          </Selector>
        </GridItem>
      </Grid>
    );
  })
  .add('with checked values (default, stateless)', () => {
    const CheckedValuesForCheckboxDemo = () => {
      const demoId = `selector-demo-${randomstring.generate(2)}`;
      const [selected, setSelected] = useState(['chocolate', 'vanilla']);

      return (
        <Grid>
          <GridItem sm={12} md={6} lg={4}>
            <Selector
              name={demoId}
              type="checkbox"
              onChange={v => {
                if (selected.includes(v)) {
                  const newSelected = remove(selected, item => v !== item);
                  setSelected(newSelected);
                } else {
                  const newSelected = concat(selected, v);
                  setSelected(newSelected);
                }

                action('onChange')(Array.isArray(v) ? v.join(', ') : v);
              }}
            >
              <SelectorItem
                id="chocolate"
                label="🍫 Chocolate"
                value="chocolate"
                checked={selected.includes('chocolate')}
              />
              <SelectorItem
                id="vanilla"
                label="🍦 Vanilla"
                value="vanilla"
                checked={selected.includes('vanilla')}
              />
              <SelectorItem
                id="strawberry"
                label="🍓 Strawberry"
                value="strawberry"
                checked={selected.includes('strawberry')}
              />
            </Selector>
          </GridItem>
        </Grid>
      );
    };

    return <CheckedValuesForCheckboxDemo />;
  })
  .add('Selector Items alone', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <>
        <Grid>
          <GridItem sm={12} md={6} lg={4}>
            <Selector name={demoId} onChange={action('onChange')}>
              <SelectorButton onClick={action('onClick')}>
                Do custom unrelated action
              </SelectorButton>
            </Selector>
          </GridItem>
        </Grid>
        <Box spacing={['pb2', 'pt2']} />
        <Grid>
          <GridItem sm={12} md={6} lg={4}>
            <Selector name={demoId} onChange={action('onChange')}>
              <SelectorItem id="option-one" label="One" value={1} />
            </Selector>
          </GridItem>
        </Grid>
      </>
    );
  })
  .add('with selector with freeform text input', () => {
    const demoId = `selector-demo-${randomstring.generate(2)}`;
    return (
      <Grid>
        <GridItem sm={12} md={6} lg={4}>
          <Selector
            name={demoId}
            type="checkbox"
            onChange={v => {
              action('onChange')(Array.isArray(v) ? v.join(', ') : v);
            }}
            value={['vanilla', 'chocolate']}
            stateful
          >
            <SelectorItem id="vanilla" label="🍦 Vanilla" value="vanilla" />
            <SelectorItem
              id="ice-cream-chocolate"
              label="🍫 Chocolate"
              value="chocolate"
            />
            <SelectorItemWithInput
              id="ice-cream-strawberry"
              label="Other (written below)"
              value="other"
              inputValue=""
              onInputChange={action('onInputChange')}
            />
          </Selector>
        </GridItem>
      </Grid>
    );
  });

Selector.displayName = 'Selector';
