import React, { ComponentType, ReactNode } from 'react'
import { Redirect, Route, RouteProps } from 'react-router'

import { useTypedSelector } from 'redux/rootReducer'
import { selectUserData } from 'redux/User/selector'
import { useQuery } from 'hooks/useQuery'

import Loading from 'components/Loading'
import { ROLE } from 'redux/User/types'
import { userHasRole } from 'utils/user'

export interface ILayoutProps {
  children: ReactNode
  showHeader?: boolean
  showSidebar?: boolean
  isExperienceFlow?: boolean
  isLivestreamFLow?: boolean
  className?: string
}

export interface IProps extends RouteProps {
  loading?: boolean
  component: ComponentType<RouteProps>
  layout: ComponentType<ILayoutProps>
  showSidebar?: boolean
  isExperienceFlow?: boolean
  isLivestreamFLow?: boolean
  className?: string
  allowedRoles?: ROLE | ROLE[] | null
}

export const ProtectedRoute = ({
  component: Component,
  layout: Layout,
  showSidebar,
  isExperienceFlow,
  isLivestreamFLow,
  className,
  allowedRoles = null,
  ...rest
}: IProps) => {
  const query = useQuery()
  const embedded = query.get('embedded')
  const user = useTypedSelector(selectUserData)
  const showHeader = !embedded

  if (allowedRoles && user) {
    const isAllowed = (
      !Array.isArray(allowedRoles) ? [allowedRoles] : allowedRoles
    ).find(allowedRole => userHasRole(user, allowedRole))

    if (!isAllowed) return <Redirect to="/admin/modules" />
  }

  return (
    <Route
      {...rest}
      render={
        props => (
          <Layout
            showHeader={showHeader}
            showSidebar={showSidebar}
            isExperienceFlow={isExperienceFlow}
            isLivestreamFLow={isLivestreamFLow}
            className={className}
          >
            {user ? <Component {...props} /> : <Loading />}
          </Layout>
        )
        //TODO: redirect to consumer if there is no access token
        // <Redirect to="/redirect-consumer" />
      }
    />
  )
}
