// @flow
import React, { useCallback, useState } 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 { Modal } from './index';
import { configDocs } from '../../../../.storybook/config-docs';
import { Head2, Text } from '../../typography';
import { Box } from '../../../primitives';
import { Button } from '../../actions/button';
import { TextInput } from '../../forms/text-input';
import { useModal } from './use-modal';
import docs from './MODAL.mkd';

const DismissibleModal = () => {
  const { showModal, onModalClose, onModalToggle } = useModal();
  return (
    <Box stacked="row">
      <Button spacing="mh4" onClick={onModalToggle}>
        Open Modal
      </Button>
      <Button
        spacing="mh4"
        onClick={() => action('onButtonClick')('Blocked Button Clicked')}
      >
        Should Be Blocked When Modal Is Open
      </Button>

      <Modal show={showModal} onClose={onModalClose}>
        <div>Something amazing I guess</div>
      </Modal>
    </Box>
  );
};

const PersistentModal = () => {
  const { showModal, onModalClose, onModalToggle } = useModal();
  return (
    <Box stacked="row">
      <Button spacing="mh4" onClick={onModalToggle}>
        Open Modal
      </Button>
      <Button
        spacing="mh4"
        onClick={() => action('onButtonClick')('Blocked Button Clicked')}
      >
        Should Be Blocked When Modal Is Open
      </Button>
      <Modal show={showModal} persistent onClose={onModalClose}>
        <Box stacked="column" align="center">
          <div>Something amazing I guess</div>
          <Button spacing="mt3" onClick={onModalClose}>
            Close
          </Button>
        </Box>
      </Modal>
    </Box>
  );
};

storiesOf('Core/Overlays/Modal', module)
  .addDecorator(withInfo(configDocs(docs, Modal)))
  .add('normal', () => (
    <Modal show onClose={action('onClose')}>
      <div>Something amazing I guess</div>
    </Modal>
  ))
  .add('medium', () => (
    <Modal show onClose={action('onClose')} size="md">
      <div>Something medium amazing I guess</div>
    </Modal>
  ))
  .add('small', () => (
    <Modal show onClose={action('onClose')} size="sm">
      <div>Something small amazing I guess</div>
    </Modal>
  ))
  .add('long body', () => (
    <Modal show onClose={action('onClose')}>
      <Box>
        <Head2>
          Are you a domestic politically exposed person, a foreign politically
          exposed person or a head of an international organization?
        </Head2>

        <Text bold>Domestic politically exposed person:</Text>
        <Text>
          A domestic PEP is a person (or the family member of a person) who
          holds — or has held within the last 5 years — an office or position in
          or on behalf of the Canadian federal government, a Canadian provincial
          government, or a Canadian municipal government: Governor General,
          lieutenant governor or head of government; member of the Senate or
          House of Commons or member of a legislature; deputy minister or
          equivalent rank; ambassador, or attaché or counsellor of an
          ambassador; military officer with a rank of general or above;
          president of a corporation that is wholly owned directly by Her
          Majesty in right of Canada or a province; head of a government agency;
          judge of an appellate court in a province, the Federal Court of Appeal
          or the Supreme Court of Canada; leader or president of a political
          party represented in a legislature; or mayor.
        </Text>

        <Text bold>Foreign politically exposed person:</Text>
        <Text>
          A foreign PEP is a person (or a family member or close associate of a
          person) who holds or has held one of the following offices or
          positions in or on behalf of a foreign state: head of state or head of
          government; member of the executive council of government or member of
          a legislature; deputy minister or equivalent rank; ambassador, or
          attaché or counsellor of an ambassador; military officer with a rank
          of general or above; president of a state-owned company or a
          state-owned bank; head of a government agency; judge of a supreme
          court, constitutional court or other court of last resort; or leader
          or president of a political party represented in a legislature. These
          persons are foreign PEPs regardless of citizenship, residence status
          or birth place.
        </Text>

        <Text bold>Head of an international organization:</Text>
        <Text>
          The head of an international organization is a person who is either:
          the head of an international organization established by the
          governments of states; or the head of an institution established by an
          international organization.
        </Text>
      </Box>
    </Modal>
  ))
  .add('xlarge', () => (
    <Modal show onClose={action('onClose')} size="xl" spacing={['ph4', 'pb4']}>
      <div>Large modal</div>
    </Modal>
  ))
  .add('hidden', () => (
    <Modal show={false} onClose={action('onClose')}>
      <div>Something amazing I guess</div>
    </Modal>
  ))
  .add('dismissible', () => <DismissibleModal />)
  .add('persistent', () => <PersistentModal />)
  .add('hide header', () => (
    <Modal show onClose={action('onClose')} size="xl" hideHeader spacing="ph2">
      <Box stacked="row">
        <BoxWithBorder spacing="p6">
          We want a full height border between this section...
        </BoxWithBorder>
        <Box spacing="p6">...and this section</Box>
      </Box>
    </Modal>
  ))
  .add('with focused content inside', () => {
    const [focusedText, setFocusedText] = useState('');
    const onFocusTextChange = useCallback(
      text => {
        action('onChange')(text);
        setFocusedText(text);
      },
      [setFocusedText],
    );

    return (
      <Modal show onClose={action('onClose')}>
        <TextInput
          label="Focus me"
          name="focus-me"
          placeholder="The modal has disableAutoFocus = true"
          onChange={onFocusTextChange}
          focusOnMount
          value={focusedText}
        />
        <TextInput label="test-2" name="test-2" onChange={action('onChange')} />
        <TextInput label="test-3" name="test-3" onChange={action('onChange')} />
      </Modal>
    );
  })
  .add('with refToRestoreFocus set', () => {
    const {
      showModal,
      onModalClose,
      onModalToggle,
      refToRestoreFocus,
    } = useModal();

    const setRefToRestoreFocus = useCallback(
      (ref: HTMLInputElement) => {
        refToRestoreFocus.current = ref;
      },
      [refToRestoreFocus],
    );

    return (
      <>
        <Button onClick={onModalToggle}>Click me to open modal</Button>
        <Box spacing="pt2">
          <TextInput
            onRef={setRefToRestoreFocus}
            label="I will be focused after close"
            onChange={action('onChange')}
          />
        </Box>

        <Modal
          show={showModal}
          onClose={onModalClose}
          refToRestoreFocus={refToRestoreFocus}
        >
          <Text>
            Its worth mentioning you should almost always restore focus to the
            button you clicked on. We are focusing to a different button to show
            the setRefToRestoreFocus
          </Text>
        </Modal>
      </>
    );
  });

const BoxWithBorder = styled(Box)`
  border-right: 1px solid lightgrey;
`;
