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

import Icon from '../../Icons/Icon'
import { type BreadcrumbType } from '../../Breadcrumbs/Common/BreadcrumbTypes'
import { useIsMobileView } from '../../../hooks/useIsMobileView/useIsMobileView'
import styles from './_left-nav-link.module.scss'
import { type LeftNavLinkObj, type LeftNavProps } from '../LeftNav'

export type LeftNavLinkProps = {
  /** The content to be displayed on the SidebarLink */
  content: LeftNavLinkObj
  /** We need the first index of the breadcrumbs array to help us determine with SidebarLink is the active link */
  firstBreadcrumb: BreadcrumbType
  /** The index is used to determine the active SidebarLink and also help create the animation effects */
  index: number
  /** This boolean is necessary to help with styling the SidebarLink when in an expanded state */
  isExpanded: boolean
  /** This boolean is necessary to help with improving the interaction on touch devices */
  isUseable: boolean
  /** This callout function is needed to update the current active index */
  setActiveBarPosition: React.Dispatch<React.SetStateAction<number>>
  /** The top position of the link container */
  topOfLinkContainer: number
  /** Component to use for routing. We need this to be defined in each application using the LeftNav. */
  routerComponent: LeftNavProps['routerComponent']
  /** Prop to use for routing within the routerComponent. We need this to be defined in each application using the LeftNav. */
  routerProp: LeftNavProps['routerProp']
  /** Function to close the LeftNav */
  close: () => void
  /** The index of the link segment to match */
  linkSegmentIndexToMatch?: number
}

const LeftNavLink = ({
  content,
  firstBreadcrumb,
  index,
  isExpanded,
  setActiveBarPosition,
  topOfLinkContainer,
  routerComponent: RouterComponent,
  routerProp,
  close,
  linkSegmentIndexToMatch,
}: LeftNavLinkProps): React.JSX.Element => {
  const [active, setActive] = useState(false)
  const elRef = useRef<HTMLDivElement>(null)
  const isMobile = useIsMobileView()
  const headerHeight = isMobile ? 49 : 73
  const linkPosition = elRef.current
    ? elRef.current.getBoundingClientRect().top - topOfLinkContainer
    : 0

  const linkCallout = () => {
    elRef.current && setActiveBarPosition(linkPosition)
    close()
  }

  useEffect(() => {
    const checkLinkMatch = () => {
      if (content.exactLinkMatch) return firstBreadcrumb?.link === content.link

      if (linkSegmentIndexToMatch) {
        // Strip any search params from URLs before comparing
        const firstBreadcrumbPath = firstBreadcrumb?.link.split('?')[0]
        const contentPath = content.link.split('?')[0]

        const firstBreadcrumbSegments = firstBreadcrumbPath?.split('/')
        const contentSegments = contentPath.split('/')

        return (
          firstBreadcrumbSegments?.[linkSegmentIndexToMatch] ===
          contentSegments?.[linkSegmentIndexToMatch]
        )
      }

      const firstBreadcrumbSegments = firstBreadcrumb?.link.split('/')
      const contentSegments = content.link.split('/')

      for (let i = 0; i < contentSegments?.length; i++) {
        if (firstBreadcrumbSegments?.[i] !== contentSegments?.[i]) {
          return false
        }
      }

      return true
    }

    if (checkLinkMatch()) {
      setActive(true)
      elRef.current && setActiveBarPosition(linkPosition)
    } else {
      setActive(false)
    }
  }, [
    setActiveBarPosition,
    content.link,
    firstBreadcrumb?.link,
    index,
    content,
    linkPosition,
    headerHeight,
    linkSegmentIndexToMatch,
  ])

  const getRouterComponentProps = () => {
    const link = content.link
    const genericProps = {
      className: `${styles.link} ${active ? styles.active : ''}`,
      onClick: linkCallout,
      [routerProp]: link,
    }

    return {
      ...genericProps,
    }
  }

  return (
    <div ref={elRef}>
      <RouterComponent {...getRouterComponentProps()}>
        <div
          className={`${styles.innerContainer} ${
            isExpanded ? styles.expanded : ''
          }`}
        >
          <Icon
            icon={content.icon}
            className={styles.sidebarLinkIcon}
            color='purple'
          />
          <span className={styles.textContainer}>
            <span
              className={`${styles.text} animated fadeInLeft`}
              style={{ animationDelay: `${index * 50}ms` }}
            >
              {content.name}
            </span>
          </span>
        </div>
      </RouterComponent>
    </div>
  )
}

export default LeftNavLink
