import React from 'react';

import { css, cx } from '@leafygreen-ui/emotion';
import { useForwardedRef } from '@leafygreen-ui/hooks';
import { useDarkMode } from '@leafygreen-ui/leafygreen-provider';
import { HTMLElementProps } from '@leafygreen-ui/lib';

import { anchorOverrides } from '../../styles';
import { orgNavLinkWrapperClassName } from '../OrgNav.styles';

import {
  activeLinkBaseStyle,
  activeLinkThemeStyle,
  displayFlex,
  navItemFocusBaseStyle,
  navItemFocusThemeStyle,
  orgNavAnchorThemeOverrides,
  orgNavLinkBaseStyle,
  orgNavLinkDisabledBaseStyle,
  orgNavLinkDisabledFocusThemeStyle,
  orgNavLinkDisabledThemeStyle,
  orgNavLinkThemeStyle,
  resetButtonStyles,
} from './OrgNavLink.styles';

interface OrgNavLinkProps
  extends HTMLElementProps<'button', HTMLButtonElement> {
  isActive?: boolean;
  href?: string;
  children?: React.ReactNode;
  className?: string;
  loading?: boolean;
  isButton?: boolean;
  onClick?: React.MouseEventHandler;
}

export const OrgNavLink = React.forwardRef<
  HTMLAnchorElement | HTMLButtonElement,
  OrgNavLinkProps
>(
  (
    {
      isActive = false,
      loading = false,
      href,
      children,
      className,
      isButton,
      onClick: onClickProp,
      disabled: disabledProp,
      ...rest
    }: OrgNavLinkProps,
    forwardedRef,
  ) => {
    const { theme } = useDarkMode();
    const ref = useForwardedRef(forwardedRef, null);

    const isDisabled = disabledProp || loading;
    const isAnchor = !(isButton && !href) && !isDisabled;
    const Component = isAnchor ? 'a' : 'button';

    const onClick = !isDisabled ? onClickProp : undefined;

    return (
      <Component
        href={href}
        disabled={isDisabled}
        aria-disabled={isDisabled}
        onClick={onClick}
        className={cx(
          resetButtonStyles,
          anchorOverrides,
          orgNavAnchorThemeOverrides[theme],
          orgNavLinkBaseStyle,
          orgNavLinkThemeStyle[theme],
          navItemFocusBaseStyle,
          navItemFocusThemeStyle[theme],
          {
            [cx(activeLinkBaseStyle, activeLinkThemeStyle[theme])]: isActive,
            [cx(
              orgNavLinkDisabledBaseStyle,
              orgNavLinkDisabledThemeStyle[theme],
              orgNavLinkDisabledFocusThemeStyle[theme],
            )]: isDisabled,
          },
          className,
        )}
        /// @ts-expect-error - TS doesn't like refs with multiple element types
        ref={ref}
        {...rest}
      >
        <span
          className={css`
            .${orgNavLinkWrapperClassName} {
              ${displayFlex};
            }
          `}
        >
          {children}
        </span>
      </Component>
    );
  },
);

OrgNavLink.displayName = 'OrgNavLink';
