import React from 'react'

export interface DropdownNavigationProps {
  selector: string
  buttonId?: string
  buttonIcon?: string
  headerContent: Exclude<React.ReactNode, (...args: any) => any>
  options: {
    id: string
    title: string
    href: string
    icon: string
    hasAccess: boolean
    hasLabel: boolean
    hasBottomLine: boolean
  }[]
  label?: Exclude<React.ReactNode, (...args: any) => any>
  trackingKey: string
  variant: 'sticky' | 'default'
}

type DropdownNavigationButtonProps = Pick<
  DropdownNavigationProps,
  'buttonId' | 'buttonIcon' | 'trackingKey' | 'variant'
>

type DropdownNavigationHeaderProps = Pick<DropdownNavigationProps, 'headerContent'>

type DropdownNavigationListProps = Pick<DropdownNavigationProps, 'options' | 'label' | 'trackingKey'>

export const DropdownNavigation = ({
  selector,
  buttonId,
  buttonIcon,
  headerContent,
  options,
  label,
  trackingKey,
  variant
}: DropdownNavigationProps) => {
  return (
    <nav
      data-o3-brand="professional"
      className={`o-header__dropdown ${selector}`}
      aria-describedby="dropdown-title"
    >
      <DropdownNavigationButton
        buttonId={buttonId}
        buttonIcon={buttonIcon}
        trackingKey={trackingKey}
        variant={variant}
      />
      <div
        className="o-header__dropdown-content"
        tabIndex={-1} // Needed so clicking inside the contnet does not lose focus from the dropdown
        id="dropdown-options"
        role="group" // Needed for VoiceOver navigation in Chrome
        data-id="dropdown-content"
      >
        <DropdownNavigationHeader headerContent={headerContent} />
        <DropdownNavigationList options={options} label={label} trackingKey={trackingKey} />
      </div>
    </nav>
  )
}

const DropdownNavigationButton: React.FC<DropdownNavigationButtonProps> = ({
  buttonId,
  buttonIcon = 'user',
  trackingKey,
  variant
}) => (
  <button
    id={buttonId}
    data-trackable={`${trackingKey}_toggle_click`}
    className="o-header__dropdown-button"
    // Tab index here is needed for making sure safari and ios browsers dropdown behavior works.
    // but the sticky header is visually hidden so prevent tabbing to there
    tabIndex={variant === 'sticky' ? -1 : 0}
    aria-label="Dropdown menu has opened on focus, press Tab to access links."
    aria-controls="dropdown-options"
  >
    <div className={`o-header__dropdown-button-user-icon-wrapper`}>
      <span className={`o-header__dropdown-icon ${buttonIcon}-icon`} aria-hidden="true" />
    </div>
    <span className="o-header__dropdown-icon chevron-icon" aria-hidden="true" />
  </button>
)

const DropdownNavigationHeader: React.FC<DropdownNavigationHeaderProps> = ({ headerContent }) => (
  <div className="o-header__dropdown-header">
    {typeof headerContent === 'string' ? (
      <span className="o-header__dropdown-title" id="dropdown-title">
        {headerContent}
      </span>
    ) : (
      <React.Fragment>{headerContent}</React.Fragment>
    )}
    <button
      className="o-header__dropdown-close-button-mobile"
      tabIndex={0} // Tab index again needed for safari and ios browsers
      aria-label="Close dropdown menu"
    />
  </div>
)

const DropdownNavigationList: React.FC<DropdownNavigationListProps> = ({ options, label, trackingKey }) => (
  <ul className="o-header__dropdown-list">
    {options.map((link) => (
      <li
        key={link.id}
        className={`o-header__dropdown-list-item${
          link.hasBottomLine ? ' o-header__dropdown-list-divider' : ''
        }`}
      >
        <a
          className="o-header__dropdown-list-item-link"
          href={link.href}
          data-trackable={`${trackingKey}_${link.id}_clicked`}
          data-tracking-key={trackingKey}
        >
          <div className="o-header__dropdown-list-item-details-container">
            <span
              className={`o-header__dropdown-icon ${link.hasAccess ? link.icon + '-icon' : 'lock-icon'}`}
              aria-hidden="true"
            />
            <span>{link.title}</span>
          </div>
          {link.hasLabel && <div className="o-header__dropdown-list-item-label-container">{label}</div>}
        </a>
      </li>
    ))}
  </ul>
)

export const ProfessionalLabel = () => (
  <span className="o-header__dropdown-list-pro-label">FT PROFESSIONAL</span>
)
