// @flow
import React, { useCallback, useState } from 'react';
import styled from 'styled-components';
import { action } from '@storybook/addon-actions';
import { Modal } from './index';
import { Head2, Text } from '../../typography';
import { Box } from '../../../primitives';
import { TertiaryButton } from '../../actions/tertiary-button';
import { TextInput } from '../../forms/text-input';
import { useModal } from './use-modal';
import { StackedChecker } from '../../../mixins/stacking/story-support/stacked-checker';
import docs from './modal.mdx';

export default {
  component: Modal,
  title: 'Components/Overlays/Modal',
  parameters: {
    docs: {
      page: docs,
    },
  },
};

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

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

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

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

export const Default = () => (
  <Modal show onClose={action('onClose')}>
    <div>Something amazing I guess</div>
  </Modal>
);

export const Medium = () => (
  <Modal show onClose={action('onClose')} size="md">
    <div>Something medium amazing I guess</div>
  </Modal>
);

export const Small = () => (
  <Modal show onClose={action('onClose')} size="sm">
    <div>Something small amazing I guess</div>
  </Modal>
);

export const LongBody = () => (
  <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>
);

export const XLarge = () => (
  <Modal show onClose={action('onClose')} size="xl" spacing={['ph4', 'pb4']}>
    <div>Large modal</div>
  </Modal>
);

export const Hidden = () => (
  <Modal show={false} onClose={action('onClose')}>
    <div>Something amazing I guess</div>
  </Modal>
);

export const Dismissible = () => <DismissibleModal />;
export const Persistent = () => <PersistentModal />;
export const HiddenHeader = () => (
  <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>
);

export const FocusedContent = () => {
  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>
  );
};

export const HeaderText = () => {
  return (
    <Modal
      show
      headerText="Transfer a chequing or savings account"
      onClose={action('onClose')}
    >
      <Box spacing="mv2">
        <Head2 align="center">Make a deposit instead</Head2>
      </Box>
      <Text align="center">
        Savings and chequing accounts can&apos;t be transferred to Wealtsimple.
        But you can move the funds to your account faster by linking a bank
        account.
      </Text>
    </Modal>
  );
};

export const BackButton = () => {
  return (
    <Modal
      show
      headerText="Transfer a chequing or savings account"
      onClose={action('onClose')}
      onBack={action('onBack')}
    >
      <Box spacing="mv2">
        <Head2 align="center">Make a deposit instead</Head2>
      </Box>
      <Text align="center">
        Savings and chequing accounts can&apos;t be transferred to Wealtsimple.
        But you can move the funds to your account faster by linking a bank
        account.
      </Text>
    </Modal>
  );
};

export const RestoresFocusTo = () => {
  const {
    showModal,
    onModalClose,
    onModalToggle,
    refToRestoreFocus,
  } = useModal();

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

  return (
    <>
      <TertiaryButton onClick={onModalToggle}>
        Click me to open modal
      </TertiaryButton>
      <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>
    </>
  );
};

export const MixinsStacked = () => <StackedChecker Component={Modal} show />;
