import React, {
  useCallback,
  useEffect,
  useLayoutEffect,
  useRef,
  useState,
} from 'react'

import Button from '../../Button/Button'
import { envColorMap, envName } from '../../../services/EnvironmentHelper'
import PatternLogo from '../../PatternLogo/PatternLogo'
import Tag from '../../Tag/Tag'
import { useTouchDeviceDetection } from '../../../hooks/useTouchDeviceDetection/useTouchDeviceDetection'
import { useWindowSize } from '../../../hooks/useWindowSize/useWindowSize'
import { type LeftNavProps } from '../LeftNav'
import styles from './_left-nav-desktop.module.scss'
import LeftNavFooter from '../Common/LeftNavFooter/LeftNavFooter'
import LeftNavLinkContainer from '../Common/LeftNavLinkContainer/LeftNavLinkContainer'
import { useHoverAndTouchSidebar } from '../Common/useHoverAndTouchSidebar'
import { type TagProps } from '../../Tag/Tag'
import { c } from '../../../translations/LibraryTranslationService'

const LeftNavDesktop = ({
  logo,
  footer,
  leftNavLinks,
  breadcrumbs,
  accountPopoverProps,
  navigate,
  heightOffset,
  environment = 'production',
  routerComponent,
  routerProp,
  languageConfig,
  hideLogo = false,
  hideCopyright = false,
  qaTestId = 'left-nav-desktop',
  linkSegmentIndexToMatch,
}: Omit<LeftNavProps, 'userPermissions'>): React.JSX.Element => {
  const [linkContainerHeight, setLinkContainerHeight] = useState<
    string | number
  >('auto')
  const sidebarRef = useRef<HTMLDivElement | null>(null)
  const logoRef = useRef<HTMLImageElement>(null)
  const headerRef = useRef<HTMLDivElement>(null)
  const linkContainerRef = useRef<HTMLDivElement>(null)
  const footerRef = useRef<HTMLDivElement>(null)
  const logoWidth = logoRef.current?.clientWidth
  const pageDimensions = useWindowSize()
  const isTouchDevice = useTouchDeviceDetection()
  const [hovered, isUseable, closeSidebar, setHovered] =
    useHoverAndTouchSidebar(sidebarRef)

  const logoCallout = () => {
    navigate()
    closeSidebar()
  }

  useLayoutEffect(() => {
    const headerHeight = headerRef.current?.clientHeight ?? 0
    const footerHeight = footerRef.current?.clientHeight ?? 0
    const heightToSubtract = headerHeight + footerHeight + (heightOffset ?? 0)
    const height = window.innerHeight - heightToSubtract
    setLinkContainerHeight(height)
  }, [pageDimensions, heightOffset])

  const calculateHeight = useCallback(() => {
    const headerHeight = headerRef.current?.clientHeight ?? 0
    const footerHeight = footerRef.current?.clientHeight ?? 0
    const heightToSubtract = headerHeight + footerHeight + (heightOffset ?? 0)
    const height = window.innerHeight - heightToSubtract
    setLinkContainerHeight(height)
  }, [heightOffset])

  useEffect(() => {
    const handleResize = () => {
      calculateHeight()
    }
    window.addEventListener('resize', handleResize)

    // Create observer to watch for size changes
    const resizeObserver = new ResizeObserver(calculateHeight)
    if (headerRef.current) {
      resizeObserver.observe(headerRef.current)
      if (footerRef.current) {
        resizeObserver.observe(footerRef.current)
      }
    }
    return () => {
      window.removeEventListener('resize', handleResize)
      resizeObserver.disconnect()
    }
  }, [calculateHeight])

  const envColor = envColorMap[environment]
  const logoMaxHeight = logo.maxHeight ? { maxHeight: logo.maxHeight } : {}

  const Logo = () => {
    const logoStyles = hovered
      ? {
          height: 24,
          marginLeft: 24,
          ...logoMaxHeight,
        }
      : { width: 50, ...logoMaxHeight }
    const logoSrc = hovered ? logo.url : logo.abbreviatedUrl

    return (
      <div
        className={`${styles.newLogoContainer} ${hovered ? styles.hovered : ''}`}
      >
        {hovered || (!hideLogo ? <PatternLogo logoSize='32px' /> : null)}
        <img src={logoSrc} alt={c('logo')} style={logoStyles} ref={logoRef} />
      </div>
    )
  }

  const EnvironmentTag = () => {
    const logoSrc = hovered ? logo.isolatedUrl : logo.abbreviatedUrl

    return (
      <div className={hovered ? styles.envTagEnv : styles.envTagLogo}>
        <Tag color={envColor as TagProps['color']}>{envName[environment]}</Tag>
        <img
          src={logoSrc}
          alt={c('logo')}
          className={`${styles.isolated} ${hovered ? styles.wide : ''}`}
          style={logoMaxHeight}
          ref={logoRef}
        />
      </div>
    )
  }

  return (
    <div
      className={`${styles.container} ${hovered ? styles.expanded : ''}`}
      ref={sidebarRef}
      style={
        logo.maxHeight
          ? ({ '--logo-max-height': logo.maxHeight } as React.CSSProperties)
          : undefined
      }
      qa-test-id={qaTestId}
    >
      {/* This is needed to prevent Sidebar elements from being clickable while Sidebar is closed. This experience should only be present for touch screen devices (except Mobile since this component is only rendered on larger devices). */}
      {isTouchDevice && !isUseable ? (
        <div className={styles.touchOverlayGuard} />
      ) : null}
      <div className={`${styles.barPlaceholder} ${styles[envColor]}`} />
      <div className={styles.navContainer}>
        <div>
          {/* logo.abbreviatedUrl && logo.isolatedUrl are added here so that only apps with the new logos are updated. Shelf is the only application that will not receive this update for now. */}
          {logo.abbreviatedUrl && logo.isolatedUrl ? (
            <div className={styles.headerContainer} ref={headerRef}>
              <Button as='unstyled' onClick={logoCallout}>
                {environment === 'production' ? <Logo /> : <EnvironmentTag />}
              </Button>
            </div>
          ) : (
            <div className={styles.headerContainer} ref={headerRef}>
              {/********************************* LOGO *********************************/}
              <Button as='unstyled' onClick={logoCallout}>
                <div
                  className={styles.logoContainer}
                  style={{ width: hovered ? logoWidth : 30 }} // 30px is the standard size of the logo when collapsed.
                >
                  <img
                    src={logo.url}
                    alt='Logo'
                    style={{
                      height: 28,
                      ...logoMaxHeight,
                    }} // We are using 28px as a default height for the logo because this works for Shelf.
                    ref={logoRef}
                  />
                </div>
              </Button>

              {/*************************** ENVIRONMENT TAG ***************************/}
              {environment !== 'production' ? (
                <div className={styles.envTag}>
                  {/* Casting here is necessary so Tag understands that these envColor options are allowed. All colors fall under TagProps['color'] so we will not have any strange behavior. */}
                  <Tag color={envColor as TagProps['color']}>
                    {envName[environment]}
                  </Tag>
                </div>
              ) : null}
            </div>
          )}

          {/**************************** NAVIGATION LINKS ****************************/}
          <div
            className={styles.barAndLinkContainer}
            style={{
              height: linkContainerHeight,
            }}
            ref={linkContainerRef}
          >
            <LeftNavLinkContainer
              containerHeight={
                typeof linkContainerHeight === 'string'
                  ? 0
                  : linkContainerHeight
              }
              containerScrollHeight={
                linkContainerRef.current?.scrollHeight ?? 0
              }
              leftNavLinks={leftNavLinks}
              breadcrumbs={breadcrumbs}
              isExpanded={hovered}
              isUseable={isUseable}
              environment={environment}
              routerComponent={routerComponent}
              routerProp={routerProp}
              close={closeSidebar}
              linkSegmentIndexToMatch={linkSegmentIndexToMatch}
            />
          </div>
        </div>

        {/********************************** FOOTER **********************************/}
        <LeftNavFooter
          expanded={hovered}
          accountPopoverProps={accountPopoverProps}
          footer={footer}
          ref={footerRef}
          closeSidebar={closeSidebar}
          openSidebar={() => setHovered(true)}
          languageConfig={languageConfig}
          hideCopyright={hideCopyright}
        />
      </div>
    </div>
  )
}

export default LeftNavDesktop
