import { useHideSidebarValue } from '@/clientsettings/vars/hidesidebar'
import ExitButton from '@/components/ExitButton'
import type { Section } from '@/components/Sidebar'
import Sidebar from '@/components/Sidebar'
import HideButton from '@/components/Sidebar/HideSidebarButton'
import Status from '@/components/Status'
import useMailToRef from '@/hooks/useMailToRef'
import { NonIdealState, Spinner, SpinnerSize } from '@blueprintjs/core'
import { cx } from '@emotion/css'
import CenteredSpinner from '@inject/shared/components/CenteredSpinner'
import ErrorMessage from '@inject/shared/components/ErrorMessage'
import NotificationDropdown from '@inject/shared/notification/NotificationDropdown'
import type { FC, PropsWithChildren } from 'react'
import { Suspense, useMemo } from 'react'
import TraineeEmailFormOverlay from '../../email/EmailFormOverlay/TraineeEmailFormOverlay'
import ChannelButton from '../ChannelButton'
import {
  contentClass,
  sidebarClass,
  sidebarClassCompact,
  viewClass,
} from '../classes'
import useTraineeViewData from './useTraineeViewData'

interface TraineeViewProps extends PropsWithChildren {
  teamId: string
  exerciseId: string
}

const TraineeView: FC<TraineeViewProps> = ({
  children,
  teamId,
  exerciseId,
}) => {
  const contentRef = useMailToRef()
  const hideLeftBar = useHideSidebarValue()

  const {
    loading,
    error,
    team,
    showExerciseTime,
    emailsEnabled,
    channels,
    loopRunning,
  } = useTraineeViewData({ teamId, exerciseId })

  const stickySections: Section[] = [
    {
      id: 'status',
      node: (
        <Status
          showTime={showExerciseTime}
          small={hideLeftBar}
          exerciseRunning={loopRunning}
          team={team}
          hideLabel={hideLeftBar}
        />
      ),
    },
  ]
  const sections: Section[] = [
    {
      id: 'options',
      name: 'Options',
      node: (
        <>
          <HideButton />
          <NotificationDropdown hideLabel={hideLeftBar} fill />
          <ExitButton hideLabel={hideLeftBar} />
        </>
      ),
    },
    {
      id: 'channels',
      name: 'Channels',
      node: (
        <>
          {loading ? (
            <Spinner size={SpinnerSize.SMALL} />
          ) : (
            channels.map(channel => (
              <ChannelButton
                key={channel.id}
                channel={channel}
                exerciseId={exerciseId}
                linkTo='trainee'
                teamId={teamId}
                hideLabel={hideLeftBar}
              />
            ))
          )}
        </>
      ),
    },
  ]

  const content = useMemo(() => {
    if (loading) {
      return <CenteredSpinner />
    }
    if (error) {
      return (
        <ErrorMessage>
          <h1>Error occurred!</h1>
          <p>{error.message}</p>
        </ErrorMessage>
      )
    }
    if (!loopRunning) {
      return (
        <NonIdealState
          icon='disable'
          title='Exercise not running'
          description='The exercise is not running, please contact your instructor.'
        />
      )
    }
    return <Suspense fallback={<CenteredSpinner />}>{children}</Suspense>
  }, [children, error, loading, loopRunning])

  return (
    <>
      {emailsEnabled && (
        <TraineeEmailFormOverlay teamId={teamId} exerciseId={exerciseId} />
      )}

      <div className={viewClass}>
        <Sidebar
          className={cx({
            [sidebarClass]: !hideLeftBar,
            [sidebarClassCompact]: hideLeftBar,
          })}
          position='left'
          sections={sections}
          stickySections={stickySections}
          hideNames={hideLeftBar}
          showLogo
        />

        <div style={{ position: 'relative', width: '100%' }}>
          <div className={contentClass} id='contentView' ref={contentRef}>
            {content}
          </div>
        </div>

        <div id='toolPanel' />
        <div id='rightPanel' />
      </div>
    </>
  )
}

export default TraineeView
