// 3rd-Party Libraries
import React from 'react';
import PropTypes from 'prop-types';

// Components
import DashHeader from '@ui/compositions/DashHeader';
import StagingFeed from '@ui/compositions/StagingFeed';
import { Button, Flex, Modal, Title } from '@ui/components';
import ModalHeader from '@ui/components/Modal/Header';
import ModalBody from '@ui/components/Modal/Body';
import ModalFooter from '@ui/components/Modal/Footer';

// Style
let classes = {};
/* istanbul ignore next */
if (typeof window !== 'undefined' || typeof _COMPILED_ === 'undefined') classes = require('./style.module.scss');

function timeSince(date) {
  const seconds = Math.floor((new Date() - date) / 1000);

  let interval = seconds / 31536000;

  if (interval > 1) {
    return `${Math.floor(interval)} years`;
  }
  interval = seconds / 2592000;
  if (interval > 1) {
    return `${Math.floor(interval)} months`;
  }
  interval = seconds / 86400;
  if (interval > 1) {
    return `${Math.floor(interval)} days`;
  }
  interval = seconds / 3600;
  if (interval > 1) {
    return `${Math.floor(interval)} hours`;
  }
  interval = seconds / 60;
  if (interval > 1) {
    return `${Math.floor(interval)} minutes`;
  }
  return `${Math.floor(seconds)} seconds`;
}

class Staging extends React.Component {
  constructor(props) {
    super(props);

    this.modal = React.createRef();
    this.state = {
      offset: 0,
    };
  }

  render() {
    const { deploy, loadMore, awaiting, deployments, deployed, modalTarget, previewLink } = this.props;

    const toggle = () => {
      this.modal.current.toggle();
    };

    const deployButtonFn = () => {
      deploy()
        .then(() => {
          this.setState({
            title: (
              <Title level={4}>
                <i
                  className={[
                    'fa fa-check-circle',
                    classes['StagingModal-HeaderIcon'],
                    classes['StagingModal-HeaderIcon_green'],
                  ].join(' ')}
                />
                Hoot Hoot Hooray
              </Title>
            ),
            body: (
              <div className={classes['StagingModal-Body_owlbert']}>
                Your changes are live and viewable by your developer community.
              </div>
            ),
            footer: (
              <React.Fragment>
                <img
                  alt="Owlbert celebrating as confetti falls"
                  className={classes['StagingModal-Owlbert_confetti']}
                  src="http://owlbert.io/images/owlberts-png/Celebration-Confetti.psd.png"
                />
                <Button onClick={toggle}>Close</Button>
              </React.Fragment>
            ),
          });
        })
        .catch(e => {
          this.setState({
            title: (
              <Title level={4}>
                <i
                  className={[
                    'fa fa-times-circle',
                    classes['StagingModal-HeaderIcon'],
                    classes['StagingModal-HeaderIcon_red'],
                  ].join(' ')}
                />
                Error
              </Title>
            ),
            body: <pre className={classes['StagingModal-Error']}>{e.data.errors.$all}</pre>,
            footer: <Button onClick={toggle}>Close</Button>,
          });
        });
    };

    const confirmationModal = {
      title: <Title level={4}>Deploying Changes</Title>,
      body: (
        <Flex layout="col">
          <div>
            Deploy your staged changes and ReadMe updates to production? You won’t be able to undo after deploying.
          </div>
          <a className={classes['StagingModal-Link']} href={previewLink} rel="noopener noreferrer" target="_blank">
            View Staged Changes
            <i className={['fa fa-arrow-circle-up', classes['StagingModal-Link-ExternalIcon']].join(' ')} />
          </a>
        </Flex>
      ),
      footer: (
        <React.Fragment>
          <Button bem={{ shale_text: true }} onClick={toggle}>
            Cancel
          </Button>
          <Button onClick={deployButtonFn}>Deploy</Button>
        </React.Fragment>
      ),
    };

    const openConfirmationModal = () => {
      this.setState(confirmationModal);
      toggle();
    };

    const lastDeployed =
      awaiting.length && deployments.length ? (
        <div className={classes['Staging-Deployed']}>
          <i className={[`icon icon-owl`]} />
          Last deployed {timeSince(new Date(deployments[0]))} ago
        </div>
      ) : null;

    const onLoadMore = () => {
      this.setState({
        offset: this.state.offset + 1,
      });
      loadMore();
    };

    const DashHeaderChildren = (
      <React.Fragment>
        <a className={classes['DashHeader-Link']} href={previewLink} rel="noopener noreferrer" target="_blank">
          <Button text={true}>
            Preview
            <i className={['fa fa-arrow-circle-up', classes['DashHeader-ExternalIcon']].join(' ')} />
          </Button>
        </a>
        <Button onClick={openConfirmationModal}>Deploy</Button>
        <Modal
          ref={this.modal}
          className={classes.StagingModal}
          onClose={() => {}}
          scrollable
          size="md"
          target={modalTarget || '#modal-target-staging'}
        >
          <ModalHeader toggleClose={toggle}>{this.state.title}</ModalHeader>
          <ModalBody>{this.state.body}</ModalBody>
          <ModalFooter>{this.state.footer}</ModalFooter>
        </Modal>
      </React.Fragment>
    );

    return (
      <React.Fragment>
        <DashHeader icon="icon icon-cloud-upload" title="Staging">
          {DashHeaderChildren}
        </DashHeader>
        <div className={classes.Staging}>
          {lastDeployed}
          <StagingFeed displayingDeployed={false} timelineContent={awaiting} title="Awaiting Deploy" />
          <StagingFeed displayingDeployed={true} loadMore={loadMore} timelineContent={deployed} title="Deployed" />
          <div className={classes['Staging-LoadMore']}>
            <Button
              disabled={deployments.length <= 1 || this.state.offset >= deployments.length - 1}
              ghost
              onClick={onLoadMore}
            >
              Load More
            </Button>
          </div>
        </div>
      </React.Fragment>
    );
  }
}

const Entry = PropTypes.shape({
  auditlogs: PropTypes.array,
  changelogs: PropTypes.array,
  date: PropTypes.instanceOf(Date),
});

Staging.propTypes = {
  awaiting: PropTypes.arrayOf(Entry).isRequired,
  deploy: PropTypes.func.isRequired,
  deployed: PropTypes.arrayOf(Entry).isRequired,
  deployments: PropTypes.arrayOf(Date).isRequired,
  loadMore: PropTypes.func.isRequired,
  modalTarget: PropTypes.string,
  previewLink: PropTypes.string.isRequired,
};
export default Staging;
