import { Route, RouteProps } from 'react-router-dom'
import { appPrivateRoutes, appPublicRoutes } from '.'
import { CreatePage } from '../pages/create'
import { HomePage } from '../pages/home'
import { LandingPage } from '../pages/landing'
import { ProfilePage } from '../pages/profile'
import { CacheSettingsPage } from '../pages/settings/cache'
import { NostrLoginPage } from '../pages/settings/nostrLogin'
import { ProfileSettingsPage } from '../pages/settings/profile'
import { RelaysPage } from '../pages/settings/relays'
import { SettingsPage } from '../pages/settings/Settings'
import { SignPage } from '../pages/sign'
import { VerifyPage } from '../pages/verify'
import { ServersPage } from '../pages/settings/servers'

/**
 * Helper type allows for extending react-router-dom's **RouteProps** with generic type
 */
type CustomRouteProps<T> = T &
  Omit<RouteProps, 'children'> & {
    children?: Array<CustomRouteProps<T>>
  }

/**
 *  This function maps over nested routes with optional condition for rendering
 *  @param {CustomRouteProps<T>[]} routes - routes list
 *  @param {RenderConditionCallbackFn} renderConditionCallbackFn - render condition callback (default true)
 */
export function recursiveRouteRenderer<T>(
  routes?: CustomRouteProps<T>[],
  renderConditionCallbackFn: (route: CustomRouteProps<T>) => boolean = () =>
    true
) {
  if (!routes) return null

  // Callback allows us to pass arbitrary conditions for each route's rendering
  // Skipping the callback will by default evaluate to true (show route)
  return routes.map((route, index) =>
    renderConditionCallbackFn(route) ? (
      <Route
        key={`${route.path}${index}`}
        path={route.path}
        element={route.element}
      >
        {recursiveRouteRenderer(route.children, renderConditionCallbackFn)}
      </Route>
    ) : null
  )
}

type PublicRouteProps = CustomRouteProps<{
  hiddenWhenLoggedIn?: boolean
}>

export const publicRoutes: PublicRouteProps[] = [
  {
    path: appPublicRoutes.landingPage,
    hiddenWhenLoggedIn: true,
    element: <LandingPage />
  },
  {
    path: appPublicRoutes.profile,
    element: <ProfilePage />
  },
  {
    path: `${appPublicRoutes.verify}/:id?`,
    element: <VerifyPage />
  }
]

export const privateRoutes = [
  {
    path: appPrivateRoutes.homePage,
    element: <HomePage />
  },
  {
    path: appPrivateRoutes.create,
    element: <CreatePage />
  },
  {
    path: `${appPrivateRoutes.sign}/:id?`,
    element: <SignPage />
  },
  {
    path: appPrivateRoutes.settings,
    element: <SettingsPage />
  },
  {
    path: appPrivateRoutes.profileSettings,
    element: <ProfileSettingsPage />
  },
  {
    path: appPrivateRoutes.cacheSettings,
    element: <CacheSettingsPage />
  },
  {
    path: appPrivateRoutes.relays,
    element: <RelaysPage />
  },
  {
    path: appPrivateRoutes.servers,
    element: <ServersPage />
  },
  {
    path: appPrivateRoutes.nostrLogin,
    element: <NostrLoginPage />
  }
]
