import React from 'react';
import styled, { css } from 'styled-components';

import type { KeyboardEvent, CSSProperties, ReactNode, PropsWithChildren, JSX } from 'react';
import type { LinkProps } from '@redocly/theme/components/Link/Link';

import { Link } from '@redocly/theme/components/Link/Link';

export type DropdownMenuItemProps = Partial<Pick<LinkProps, 'to' | 'target' | 'external'>> & {
  prefix?: ReactNode;
  suffix?: ReactNode;
  content?: ReactNode;

  separatorLine?: boolean;

  dataAttributes?: Record<string, string>;
  className?: string;
  style?: CSSProperties;
  role?: string;

  separator?: boolean;
  disabled?: boolean;
  dangerous?: boolean;
  onAction?: () => void;
  active?: boolean;
};

export function DropdownMenuItem({
  children,
  content,
  active,
  onAction,
  to,
  dangerous,
  prefix,
  suffix,
  disabled,
  separator,
  dataAttributes,
  className,
  separatorLine,
  style,
  role = 'menuitem',
  ...otherProps
}: PropsWithChildren<DropdownMenuItemProps>): JSX.Element {
  const handleClick = () => {
    onAction?.();
  };

  const handleKeyDown = (event: KeyboardEvent) => {
    if (event.key === 'Enter' || event.key === ' ') {
      onAction?.();
    }
  };

  className = className || '' + (active ? ' active' : '');

  const sharedProps = {
    $active: active,
    $dangerous: dangerous,
    $disabled: disabled,
    $separator: separator,
    $separatorLine: separatorLine,
    'data-component-name': 'Dropdown/DropdownMenuItem',
    className,
    onClick: handleClick,
    role,
    style,
  };

  if (to) {
    return (
      <DropdownMenuItemWrapper
        as={Link}
        to={to}
        {...sharedProps}
        {...dataAttributes}
        {...otherProps}
      >
        {prefix}
        {children}
        {suffix}
      </DropdownMenuItemWrapper>
    );
  }

  return (
    <DropdownMenuItemWrapper
      {...sharedProps}
      {...dataAttributes}
      onKeyDown={handleKeyDown}
      tabIndex={onAction ? 0 : -1}
    >
      {prefix}
      {children || content}
      {suffix}
    </DropdownMenuItemWrapper>
  );
}

const DropdownMenuItemWrapper = styled.li<{
  $separatorLine?: boolean;
  $separator?: boolean;
  $active?: boolean;
  $disabled?: boolean;
  $dangerous?: boolean;
}>`
  display: flex;
  flex-direction: row;
  justify-content: var(--dropdown-menu-item-justify-content, flex-start);
  align-items: center;
  width: 100%;
  border: none;
  background: none;
  appearance: none;
  text-align: left;
  gap: var(--spacing-xxs);

  > * {
    min-width: 0; // for flex
  }

  cursor: pointer;
  pointer-events: auto;

  padding: var(--dropdown-menu-item-padding-vertical) var(--dropdown-menu-item-padding-horizontal);
  border-radius: var(--dropdown-menu-item-border-radius);

  &:focus-visible {
    outline: 1px solid var(--dropdown-menu-item-border-color-focused);
  }

  background-color: var(--dropdown-menu-item-bg-color);
  color: var(--dropdown-menu-item-color);

  text-decoration: none;

  &:hover {
    background-color: var(--dropdown-menu-item-bg-color-hover);
    color: var(--dropdown-menu-item-color-hover);
  }

  ${({ $separator }) =>
    $separator &&
    css`
      cursor: default;
      pointer-events: none;
      font-size: var(--dropdown-menu-item-separator-font-size);
      line-height: var(--dropdown-menu-item-separator-line-height);
      color: var(--dropdown-menu-item-separator-text-color);
      --dropdown-menu-item-bg-color-hover: var(--dropdown-menu-item-bg-color);
    `}

  ${({ $active }) =>
    $active &&
    css`
      background-color: var(--dropdown-menu-item-bg-color-active);
      color: var(--dropdown-menu-item-color-active);
      svg {
        fill: var(--dropdown-menu-item-color-active);
      }
    `}

  ${({ $disabled }) =>
    $disabled &&
    css`
      cursor: default;
      pointer-events: none;
      background-color: var(--dropdown-menu-item-bg-color-disabled);
      color: var(--dropdown-menu-item-color-disabled);
      svg {
        fill: var(--dropdown-menu-item-color-disabled);
      }
    `}

  ${({ $separatorLine }) =>
    $separatorLine &&
    css`
      border-bottom: 1px solid var(--dropdown-menu-item-separator-border-color);
      border-bottom-left-radius: 0;
      border-bottom-right-radius: 0;
      margin-bottom: var(--dropdown-menu-item-padding-vertical);
      &:empty {
        padding-top: 0;
        padding-bottom: 0;
        margin-top: var(--dropdown-menu-item-padding-vertical);
      }
    `}

  ${({ $dangerous }) =>
    $dangerous &&
    css`
      &:hover,
      & {
        color: var(--dropdown-menu-item-color-dangerous);
        svg {
          fill: var(--dropdown-menu-item-color-dangerous);
        }
      }
    `}
`;
