// @flow
import React, { useState, useCallback } from 'react';
import styled from 'styled-components';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { withInfo } from '@storybook/addon-info';
import { TextInput } from './index';
import type { TextInputProps } from './text-input.proptypes';
import { Grid, GridItem } from '../../structures';
import { configDocs } from '../../../../.storybook/config-docs';
import docs from './TEXT_INPUT.mkd';

const TextInputDemo = ({
  value,
  large,
  iconType,
  iconPosition,
  label,
  placeholder = "Look a placeholder that's really long!",
  onFocus,
  onBlur,
  disabled,
  error,
  focusOnMount,
  mask,
  maskOptions,
  onChange,
  className = '',
  buttonText,
  inputMode,
  hideBorder = false,
}: TextInputProps<string>) => {
  const [demoValue, setDemoValue] = useState(value);
  const handleValueChanged = useCallback(
    (newValue, event) => {
      setDemoValue(newValue);
      onChange(newValue, event);
    },
    [onChange],
  );

  return (
    <TextInput
      label={label}
      onChange={handleValueChanged}
      value={demoValue}
      iconType={iconType}
      iconPosition={iconPosition}
      placeholder={placeholder}
      onFocus={onFocus}
      onBlur={onBlur}
      large={large}
      disabled={disabled}
      error={error}
      focusOnMount={focusOnMount}
      className={className}
      mask={mask}
      maskOptions={maskOptions}
      buttonText={buttonText}
      inputMode={inputMode}
      hideBorder={hideBorder}
    />
  );
};

const StyledTextInputDemo = styled(TextInputDemo)`
  width: 400px;
  padding-right: 25px;
  border: 5px solid red;
`;

export const textInputWithButtonTextStory = (
  <TextInputDemo label="" onChange={action('onChange')} buttonText="Show" />
);

export const textInputWithButtonTextWithErrorStory = (
  <TextInputDemo
    label=""
    onChange={action('onChange')}
    buttonText="Show"
    error
  />
);

storiesOf('Core/Forms/TextInput', module)
  .addDecorator(withInfo(configDocs(docs, TextInput)))
  .addDecorator((story) => (
    <Grid>
      <GridItem sm={12} md={6} lg={4}>
        {story()}
      </GridItem>
    </Grid>
  ))
  .add('normal', () => <TextInputDemo label="" onChange={action('onChange')} />)
  .add('large', () => (
    <TextInputDemo label="" large onChange={action('onChange')} />
  ))
  .add('with button text', () => textInputWithButtonTextStory)
  .add(
    'with button text with error',
    () => textInputWithButtonTextWithErrorStory,
  )
  .add('with value (disabled)', () => (
    <TextInputDemo
      label="Omg a label"
      disabled
      placeholder="Look a placeholder that's really long!"
      value="Wooo a value!"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
    />
  ))
  .add('with icon (left)', () => (
    <TextInputDemo
      label="Omg a label"
      iconType="lock"
      iconPosition="left"
      placeholder="Look a placeholder that's really long!"
      value="Wooo a value!"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
    />
  ))
  .add('with icon (right)', () => (
    <TextInputDemo
      label="Omg a label"
      iconType="lock"
      iconPosition="right"
      placeholder="Look a placeholder that's really long!"
      value="Wooo a value!"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
    />
  ))
  .add('with checkmark icon (right) with large input', () => (
    <TextInputDemo
      label="Omg a label"
      iconType="checkmark"
      iconPosition="right"
      placeholder="Look a placeholder that's really long!"
      value="Wooo a value!"
      large
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
    />
  ))
  .add('with icon (right, disabled)', () => (
    <TextInputDemo
      label="Omg a label"
      iconType="lock"
      iconPosition="right"
      disabled
      placeholder="Look a placeholder that's really long!"
      value="Wooo a value!"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
    />
  ))
  .add('with icon with error', () => (
    <TextInputDemo
      label="Omg a label"
      iconType="lock"
      iconPosition="right"
      error
      placeholder="Look a placeholder that's really long!"
      value="Wooo a value!"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
    />
  ))
  .add('with error', () => (
    <TextInputDemo
      label="Omg a label"
      placeholder="Look a placeholder that's really long!"
      value="O no, an error"
      error
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
    />
  ))
  .add('error (string)', () => (
    <TextInputDemo
      label="Omg a label"
      placeholder="Look a placeholder that's really long!"
      value="O no, an error"
      error="dangnamit I'm broken"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      large
    />
  ))
  .add('error (array)', () => (
    <TextInputDemo
      label="Omg a label"
      placeholder="Look a placeholder that's really long!"
      value="O no, an error"
      error={["dangnamit I'm broken", "dangnamit I'm broken"]}
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      large
    />
  ))
  .add('focused on mount', () => (
    <TextInputDemo
      label="Omg a label"
      placeholder="Look a placeholder that's really long!"
      value="Your input here"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      focusOnMount
    />
  ))
  .add('with extended styles', () => (
    <StyledTextInputDemo
      label="Omg a label"
      placeholder="Look a placeholder that's really long!"
      value="Your input here"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      focusOnMount
    />
  ))
  .add('with a date formatting mask', () => (
    <TextInputDemo
      label="Enter a date"
      placeholder="DD / MM / YYYY"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      mask
      maskOptions={{
        date: true,
        datePattern: ['d', 'm', 'Y'],
        delimiter: ' / ',
      }}
    />
  ))
  .add('with a date formatting mask - large', () => (
    <TextInputDemo
      label="Enter a date"
      placeholder="DD / MM / YYYY"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      mask
      maskOptions={{
        date: true,
        datePattern: ['d', 'm', 'Y'],
        delimiter: ' / ',
      }}
    />
  ))
  .add('with a date formatting mask - large', () => (
    <TextInputDemo
      label="Enter a date"
      placeholder="DD / MM / YYYY"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      mask
      maskOptions={{
        date: true,
        datePattern: ['d', 'm', 'Y'],
        delimiter: ' / ',
      }}
      large
    />
  ))
  .add('with a date formatting mask - error', () => (
    <TextInputDemo
      label="Enter a date"
      placeholder="DD / MM / YYYY"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      mask
      maskOptions={{
        date: true,
        datePattern: ['d', 'm', 'Y'],
        delimiter: ' / ',
      }}
      error="dangnamit I'm broken"
    />
  ))
  .add('with a date formatting mask - focus on mount', () => (
    <TextInputDemo
      label="Enter a date"
      placeholder="DD / MM / YYYY"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      mask
      maskOptions={{
        date: true,
        datePattern: ['d', 'm', 'Y'],
        delimiter: ' / ',
      }}
      focusOnMount
    />
  ))
  .add('with a date formatting mask - icon left', () => (
    <TextInputDemo
      label="Enter a date"
      placeholder="DD / MM / YYYY"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      mask
      maskOptions={{
        date: true,
        datePattern: ['d', 'm', 'Y'],
        delimiter: ' / ',
      }}
      iconType="lock"
      iconPosition="left"
    />
  ))
  .add('with a date formatting mask - icon right', () => (
    <TextInputDemo
      label="Enter a date"
      placeholder="DD / MM / YYYY"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      mask
      maskOptions={{
        date: true,
        datePattern: ['d', 'm', 'Y'],
        delimiter: ' / ',
      }}
      iconType="lock"
      iconPosition="right"
    />
  ))
  .add('with a date formatting mask - extended styles', () => (
    <StyledTextInputDemo
      label="Enter a date"
      placeholder="DD / MM / YYYY"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      mask
      maskOptions={{
        date: true,
        datePattern: ['d', 'm', 'Y'],
        delimiter: ' / ',
      }}
    />
  ))
  .add('with a phone formatting mask', () => (
    <TextInputDemo
      label="Enter a phone number (CA)"
      placeholder="555 444 3333"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      type="number"
      mask
      maskOptions={{
        phone: true,
        phoneRegionCode: 'CA',
      }}
    />
  ))
  .add('with inputMode numeric', () => (
    <TextInputDemo
      label="Enter a number"
      placeholder="2"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      inputMode="numeric"
      type="number"
    />
  ))
  .add('with currency mask', () => (
    <TextInputDemo
      label="Enter a number"
      placeholder="$0.00"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      mask
      maskOptions={{
        numeral: true,
        prefix: '$',
        noImmediatePrefix: true,
        rawValueTrimPrefix: true,
      }}
      focusOnMount={false}
    />
  ))
  .add('with currency mask - focus on mount', () => (
    <TextInputDemo
      label="Enter a number"
      placeholder="$0.00"
      onChange={action('onChange')}
      onFocus={action('onFocus')}
      onBlur={action('onBlur')}
      mask
      maskOptions={{
        numeral: true,
        prefix: '$',
        noImmediatePrefix: true,
        rawValueTrimPrefix: true,
      }}
      focusOnMount
    />
  ))
  .add('normal - hide border', () => (
    <TextInputDemo label="Label" onChange={action('onChange')} hideBorder />
  ));
