import React, { Suspense, useContext, useEffect, useMemo } from 'react'

import { I18nContext } from 'react-i18next'
import { Navigate, useParams } from 'react-router-dom'

import LoadingSpin from '~/components/LoadingSpin'
import { RemoteNamespace, globalAddTranslations } from '~/translations'

import HealthReport from './Report'
import healthTranslations, { HEALTH_REPORT_NS } from './translations'

// Add local translations for health report
globalAddTranslations(healthTranslations, HEALTH_REPORT_NS)

type ParamsValidHashmap = {
  org: boolean
  cluster: boolean
  report: boolean
}

type Param = {
  orgId?: string
  clusterId?: string
  reportId?: string
}

/**
 * Redirection table for handling invalid parameters
 */
const redirectionTable = [
  {
    compute: (validHashmap: ParamsValidHashmap) =>
      validHashmap.org && validHashmap.cluster && validHashmap.report,
    toPath: (param: Param) => ''
  },
  {
    compute: (validHashmap: ParamsValidHashmap) =>
      validHashmap.org && validHashmap.cluster && !validHashmap.report,
    toPath: (param: Param) => `/orgs/${param.orgId}/clusters/${param.clusterId}`
  },
  {
    compute: (validHashmap: ParamsValidHashmap) =>
      validHashmap.org && !validHashmap.cluster,
    toPath: (param: Param) => `/orgs/${param.orgId}`
  },
  {
    compute: (validHashmap: ParamsValidHashmap) => !validHashmap.org,
    toPath: (param: Param) => `/orgs`
  }
]

/**
 * Check if the parameter is valid
 */
const isValidParam = (param: string | undefined) =>
  !!param && param !== 'undefined' && param !== 'null'

const HealthReportWrapper: React.FC = () => {
  const {
    orgId,
    cid: clusterId,
    reportId
  } = useParams<'orgId' | 'cid' | 'reportId'>()

  // Compute and get redirection path
  const redirectPath = useMemo(() => {
    const validHashmap = {
      org: isValidParam(orgId),
      cluster: isValidParam(clusterId),
      report: isValidParam(reportId)
    }

    const target = redirectionTable.find(({ compute }) => compute(validHashmap))

    const redirectPath = target?.toPath({
      orgId,
      clusterId,
      reportId
    })

    return redirectPath
  }, [orgId, clusterId, reportId])

  const { i18n } = useContext(I18nContext) || {}

  // Load i18n remote resources for health report
  useEffect(() => {
    i18n?.loadNamespaces([RemoteNamespace.Metrics, RemoteNamespace.Log])
  }, [i18n])

  if (redirectPath) {
    return <Navigate to={redirectPath} />
  }

  return (
    <Suspense fallback={<LoadingSpin />}>
      <HealthReport
        orgId={orgId!}
        clusterId={clusterId!}
        reportId={reportId!}
      />
    </Suspense>
  )
}

export default HealthReportWrapper
