import React from 'react';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router';
import { always } from 'ramda';

// TODO: This needs to eventually move into config file
const publicPaths = ['/', '/login', '/unauthorized', '/404'];

class Auth extends React.PureComponent {
  constructor(props) {
    super(props);
    const {
      resetPermissions, loggedin, location: { pathname }, router, loginPath
    } = props;
    resetPermissions();

    if (!loggedin && pathname !== loginPath) {
      router.push(loginPath);
    }
  }

  componentDidMount() {
    const { authorise, location: { pathname } } = this.props;
    if (!publicPaths.includes(pathname)) authorise({ resource: pathname, domain: 'www', method: 'GET' });
  }

  componentDidUpdate() {
    const {
      authorise, location: { pathname }, resource, ioRequestStatus,
      unauthorisedPath, router, isAuthorised
    } = this.props;

    if (
      ioRequestStatus === 'SUCCESS'
      && !publicPaths.includes(pathname)
      && (pathname === resource)
      && !isAuthorised
    ) {
      router.push(unauthorisedPath);
      return;
    }

    if (
      !publicPaths.includes(pathname)
      && (pathname !== resource)
      && (ioRequestStatus !== 'PENDING')
      && (ioRequestStatus !== 'ERROR')
    ) authorise({ resource: pathname, domain: 'www', method: 'GET' });
  }

  render() {
    const {
      isAuthorised,
      location: { pathname },
      children,
      ioRequestStatus,
    } = this.props;

    if (ioRequestStatus === 'PENDING') {
      return (
        <p>
          LOADING...
        </p>);
    }

    return (
      isAuthorised || publicPaths.includes(pathname) ? (
        React.cloneElement(children, {})
      ) : null
    );
  }
}


Auth.propTypes = {
  children: PropTypes.node,
  isAuthorised: PropTypes.bool,
  authorise: PropTypes.func,
  resetPermissions: PropTypes.func,
  location: PropTypes.shape({
    pathname: PropTypes.string,
  }),
  router: PropTypes.shape({
    push: PropTypes.func,
  }),
  resource: PropTypes.string,
  loggedin: PropTypes.bool,
  loginPath: PropTypes.string,
  ioRequestStatus: PropTypes.string,
  unauthorisedPath: PropTypes.string,
};

Auth.defaultProps = {
  children: '',
  isAuthorised: false,
  authorise: always(),
  resetPermissions: always(),
  location: {
    pathname: '',
  },
  router: {},
  resource: '',
  loggedin: false,
  loginPath: '',
  ioRequestStatus: '',
  unauthorisedPath: '',
};

const WrappedAuth = withRouter(Auth);

export default WrappedAuth;
