import React, { useEffect } from 'react'
import { createPortal } from 'react-dom'

import Button from '../Button/Button'
import ButtonGroup from '../Button/ButtonGroup/ButtonGroup'
import isClient from '../../services/isClient'
import Pagination from '../Pagination/Pagination'
import { useIsMobileView } from '../../hooks/useIsMobileView/useIsMobileView'
import styles from './_page-footer.module.scss'
import { c } from '../../translations/LibraryTranslationService'

type ButtonType = React.ComponentProps<typeof Button>
type ButtonGroupType = React.ComponentProps<typeof ButtonGroup>
type PaginationType = React.ComponentProps<typeof Pagination>

type ButtonProp = {
  type: 'button'
} & ButtonType

type ButtonGroupProps = {
  type: 'buttonGroup'
} & ButtonGroupType

type PaginationProps = {
  type: 'pagination'
} & PaginationType

type ButtonProps = ButtonProp | ButtonGroupProps

type LeftSectionProps = ButtonProps | PaginationProps

export type PageFooterProps = {
  /** Right section props can include 1 - 3 Buttons */
  rightSection?: ButtonProps[]
  /** Optional : Left section props includes a single Button or Pagination */
  leftSection?: LeftSectionProps
  /** Optional : Override default width calculation */
  customWidth?: string
  /** Optional : Override default class */
  customClass?: string
  /** Optional prop to add a test id to the PageFooter for QA testing */
  qaTestId?: string
}

const PageFooter = ({
  leftSection,
  rightSection,
  customWidth,
  customClass,
  qaTestId = 'page-footer',
}: PageFooterProps): React.JSX.Element => {
  const isMobileView = useIsMobileView()

  if (!leftSection && !rightSection) {
    throw new Error(c('errorPageFooterNeedsContent'))
  }

  useEffect(() => {
    const element = document.querySelectorAll<HTMLElement>('.App-content')?.[0]
    element?.classList?.add('has-page-footer')

    return () => {
      element?.classList?.remove('has-page-footer')
    }
  }, [])

  return isClient ? (
    createPortal(
      <div
        className={`${styles.container} ${customClass ?? ''}`}
        style={{
          width: customWidth
            ? customWidth
            : !isMobileView
              ? 'calc(100vw - 112px)'
              : 'calc(100vw - 40px)', // 112px is the width of a collapsed Sidebar and left/right padding inside the PageFooter. 40px represents the left/right padding of the PageFooter.
        }}
        qa-test-id={qaTestId}
      >
        {leftSection ? <LeftSection {...leftSection} /> : <div />}
        {rightSection ? <RightSection buttons={rightSection} /> : <div />}
      </div>,
      document.querySelector('body') as HTMLBodyElement,
    )
  ) : (
    <></>
  )
}

export default PageFooter

const LeftSection = (props: LeftSectionProps): React.JSX.Element => {
  const { type } = props
  const view = {
    pagination: type === 'pagination' && <Pagination {...props} />,
    button: type === 'button' && <Button {...props} />,
    buttonGroup: type === 'buttonGroup' && <ButtonGroup {...props} />,
  }[type]

  return <div className={styles.sectionContainer}>{view}</div>
}

const RightSection = ({
  buttons,
}: {
  buttons: ButtonProps[]
}): React.JSX.Element => {
  if (buttons.length > 3) {
    throw new Error(c('errorPageFooterRightSection'))
  }

  return (
    <div className={styles.sectionContainer}>
      {buttons.map((button, index) => {
        return button.type === 'buttonGroup' ? (
          <ButtonGroup key={index} {...button} />
        ) : (
          <Button key={index} {...button} />
        )
      })}
    </div>
  )
}
