import React from 'react'

import isClient from '../../services/isClient'
import { useWindowSize } from '../../hooks/useWindowSize/useWindowSize'
import { useMediaQuery } from '../../hooks/responsiveHooks'

export type StickyTableContainerProps = {
  children: React.ReactNode
  hasData: boolean
  loading: boolean
  customWidth?: number | string
  customHeight?: number | string
  /** If the table is next to another element, the computed width of the table will be incorrect. Use this to input the width of the element (including padding, margin, and other spacing) to have the correct width for the table. */
  widthOffset?: number
  /** Optional prop to add a test id to the StickyTableContainer for QA testing */
  qaTestId?: string
}

export const StickyTableContainer = ({
  children,
  hasData,
  loading,
  customWidth,
  customHeight,
  widthOffset = 0,
  qaTestId = 'sticky-table-container',
}: StickyTableContainerProps): React.JSX.Element => {
  const containerDimensions = useWindowSize()
  const screenIsMdMin = useMediaQuery({ type: 'min', breakpoint: 'md' })
  const sidebarWidth = isClient
    ? Number(
        getComputedStyle(document.documentElement).getPropertyValue(
          '--sidebar-collapsed-width',
        ),
      )
    : 0
  const headerHeight = isClient
    ? Number(
        getComputedStyle(document.documentElement).getPropertyValue(
          '--header-height',
        ),
      )
    : 0
  // We only need the width calculation if the table has sticky columns
  const standardWidth = containerDimensions.width
    ? containerDimensions.width -
      sidebarWidth -
      widthOffset -
      (screenIsMdMin /* We only need this on MD screens or larger. Otherwise, if a table is in mobile (and not using the MobileTable) then this removes 40px more than needed. */
        ? 40 /* Magic number to account for padding of the .app-content-layout container*/
        : 0)
    : '100%'
  const standardHeight =
    containerDimensions.height && containerDimensions.height - headerHeight

  const style: React.CSSProperties = {
    width: customWidth ?? standardWidth,
    height:
      hasData || loading
        ? customHeight
          ? customHeight
          : standardHeight
        : 'auto' /* If no data is present and also not loading, we do not want the table height to be too tall so we can show the EmptyState component under the table */,
  }

  return (
    containerDimensions && (
      <div style={style} qa-test-id={qaTestId}>
        {children}
      </div>
    )
  )
}

export default StickyTableContainer
