import React from 'react'

import CsvExport from '../CsvExport/CsvExport'
import { type CsvExportProps } from '../CsvExport/CsvExport'
import Filter from '../Filter/Filter'
import { type FilterProps } from '../Filter/Filter'
import Icon from '../Icons/Icon'
import Image from '../Image/Image'
import { type ImageProps } from '../Image/Image'
import SearchBar from '../SearchBar/SearchBar'
import { type SearchBarProps } from '../SearchBar/SearchBar'
import { Skeleton } from '../Skeleton/Skeleton'
import Tooltip from '../Tooltip/Tooltip'
import { type TooltipProps } from '../Tooltip/Tooltip'
import { useMediaQuery } from '../../hooks/responsiveHooks'
import styles from './_page-header.module.scss'

type HeaderWithName = {
  name: React.ReactNode
  value: React.ReactNode
  tooltip?: TooltipProps
  image?: never
}

type HeaderWithImage = {
  image: ImageProps
  name?: never
  value?: never
  tooltip?: never
}

export type PageHeaderProps<OptionType> = {
  /** Header name, value, and optional tooltip */
  header?: HeaderWithName | HeaderWithImage
  /** Optional `SearchBar` available */
  search?: SearchBarProps
  /** Optional `CsvExport` available */
  download?: CsvExportProps
  /** Optional page filter available */
  pageFilterProps?: FilterProps<OptionType>
  /** Optional informational `Tooltip` available */
  tooltip?: Omit<TooltipProps, 'children'>
  /** Optionally children to appear in the left section of the `PageHeader` */
  leftSectionChildren?: React.ReactNode
  /** Optionally children to appear in the right section of the `PageHeader` */
  rightSectionChildren?: React.ReactNode
  /** Optionally children to appear in the bottom section of the `PageHeader` */
  bottomSectionChildren?: React.ReactNode
  /** Optionally hide the right section divider in mobile */
  hideMobileDivider?: boolean
  /** Optionally add loaders */
  loading?: {
    headerName?: boolean
    headerValue?: boolean
    headerImage?: boolean
  }
  /** Optional prop to add a test id to the PageHeader for QA testing */
  qaTestId?: string
}

const PageHeader = <OptionType,>({
  header,
  search,
  download,
  tooltip,
  pageFilterProps,
  leftSectionChildren,
  rightSectionChildren,
  bottomSectionChildren,
  hideMobileDivider,
  loading,
  qaTestId = 'page-header',
}: PageHeaderProps<OptionType>): React.JSX.Element => {
  const rightSectionOptionsCheck = rightSectionChildren || download || tooltip
  const rightSectionCheck = rightSectionOptionsCheck || pageFilterProps
  const isMobileView = useMediaQuery({ type: 'max', breakpoint: 'sm' })
  return (
    <div className={styles.pageHeaderContainer} qa-test-id={qaTestId}>
      <div
        className={`${styles.mainSection} ${pageFilterProps ? styles.hasFilter : ''}`}
      >
        <div className={styles.leftSection}>
          {/* Main Header name, value, and optional Tooltip */}
          {header ? (
            header.image ? (
              loading?.headerImage ? (
                <Skeleton width={40} height={40} borderRadius={50} />
              ) : (
                <Image
                  style={{
                    margin: 0 /** This override is needed because ProductImage has a margin by default that we do not want. */,
                  }}
                  {...header.image}
                />
              )
            ) : (
              <div className={styles.headerContainer}>
                <div className={styles.headerAndTooltipContainer}>
                  {loading?.headerName ? <Skeleton width={75} /> : header.name}
                  {header.tooltip ? (
                    <Tooltip {...header.tooltip}>
                      <Icon icon='info' iconSize='16px' color='dark-blue' />
                    </Tooltip>
                  ) : null}
                </div>
                {loading?.headerValue ? (
                  <div className={styles.headerValueSkeleton}>
                    <Skeleton />
                  </div>
                ) : (
                  <div className={styles.headerValue}>{header.value}</div>
                )}
              </div>
            )
          ) : null}
          {/* Optional leftSectionChildren */}
          {leftSectionChildren ? leftSectionChildren : null}
          {header && search ? <Divider large /> : null}
          {/* Optional SearchBar */}
          {search ? <SearchBar {...search} /> : null}
        </div>
        {rightSectionCheck ? (
          <div className={styles.rightSection}>
            {isMobileView && !hideMobileDivider ? <Divider horizontal /> : null}
            {/* Optional download */}
            {download ? <CsvExport {...download} /> : null}
            {/* Optional informational Tooltip */}
            {tooltip ? (
              <Tooltip {...tooltip}>
                <Icon icon='info' iconSize='20px' color='dark-blue' />
              </Tooltip>
            ) : null}
            {rightSectionOptionsCheck && pageFilterProps ? <Divider /> : null}
            {/* Optional filters */}
            {pageFilterProps ? <Filter {...pageFilterProps} /> : null}
            {/* Optional rightSectionChildren */}
            {rightSectionChildren ? rightSectionChildren : null}
          </div>
        ) : null}
      </div>
      {/* Optional bottomSectionChildren */}
      {bottomSectionChildren ? bottomSectionChildren : null}
    </div>
  )
}

const Divider = ({
  large,
  horizontal,
}: {
  large?: boolean
  horizontal?: boolean
}) => {
  return (
    <div
      className={`${styles.divider} ${large ? styles.large : ''} ${horizontal ? styles.horizontal : ''}`}
    />
  )
}

PageHeader.HeaderDivider = Divider

export { PageHeader }
