/* global APP_HOSTNAME */

import React from 'react'
import PropTypes from 'prop-types'
import {Redirect, Route} from 'react-router-dom'
import PageNotFound from 'containers/pages/not-found'
import Debug from 'common-fe/utils/debug'
import routes from 'global/constants/routes'
import {isOnboardingRoute} from 'utils/route'

class GuardedRoute extends React.PureComponent {
    // STATIC PROPERTIES =======================================================
    static getDerivedStateFromProps({location, policy}) {
        if (!policy.isReady) {
            return null
        }

        // The route can be resolved if our policy is ready
        const {isAuthorized} = policy.forLocation(location)
        return {
            isAuthenticated: policy.isAuthenticated,
            isAuthorized,
            isResolved: true,
        }
    }

    // INSTANCE PROPERTIES =====================================================
    state = {isAuthenticated: false, isAuthorized: false, isResolved: false}

    get isAuthenticated() {
        return this.state.isAuthenticated
    }

    get isAuthorized() {
        return this.state.isAuthorized
    }

    get isOnboarded() {
        return this.props.policy.isOnboarded
    }

    get isResolved() {
        return this.state.isResolved
    }

    get isSubscriptionActive() {
        return this.props.policy.isSubscriptionActive
    }

    render() {
        const {
            location: {pathname, search, hash},
            path,
            policy,
            ...rest
        } = this.props

        if (!this.isResolved) {
            return null
        }

        // If a user is unauthenticated, then they have yet to successfully log in.
        // In this case, we will redirect them to the account management app to
        // authenticate themselves.
        if (!this.isAuthenticated) {
            Debug.group(
                `[GuardedRoute] User Not Authenticated/Verified: Redirect to Login (${routes.LOGIN})`
            )

            if (window.location.hostname !== APP_HOSTNAME) {
                Debug.log(
                    `To provide a better development experience, we only redirect to login when the hostname is "${APP_HOSTNAME}"`
                )
            } else {
                window.location.href = routes.LOGIN
            }

            Debug.groupEnd()
            return null
        }

        // Redirect to start onboarding if user not onboarded
        if (!this.isOnboarded && !isOnboardingRoute(pathname)) {
            return <Redirect to={{pathname: routes.ONBOARD, search, hash}} />
        } else if (this.isOnboarded && routes.regex.ONBOARD.test(pathname)) {
            return <Redirect to={{pathname: routes.HOME, search, hash}} />
        }

        // If the user is not authorized to view this page, we render page not found
        if (!this.isAuthorized) {
            Debug.log(`[GuardedRoute] User Not Authorized to view this page.`)
            return <PageNotFound />
        }

        // If the route is the index route '/', we redirect to the appropriate
        // home page based on the user's roles
        if (routes.regex.HOME.test(pathname)) {
            if (policy.isProfessor) {
                return <Redirect to={{pathname: routes.COURSE, search, hash}} />
            }

            if (policy.isParticipant) {
                return (
                    <Redirect to={{pathname: routes.PORTFOLIO, search, hash}} />
                )
            }
        }

        return <Route {...rest} path={path} />
    }
}

GuardedRoute.propTypes = {
    policy: PropTypes.object.isRequired,
    location: PropTypes.object,
    path: PropTypes.string,
}

export default GuardedRoute
