import { forwardRef, useCallback } from "react";
import { useCursor } from "../button/hook/useCursor";
import { StyledLinkButton } from "./link-button.styled";
import type { WithTestId } from "../../types";

export interface LinkButtonProps extends WithTestId<React.ComponentProps<typeof StyledLinkButton>> {
  /**
   * @deprecated Will be removed in 1.0.0. Use `children` instead
   * The content of the LinkButton
   */
  text?: string | null | undefined;
  /**
   * The redirect url of the LinkButton
   */
  href: string;
  /**
   * If passed as string the button link will automatically handle the styling.
   * Should be non-interactive phrasing content.
   */
  children?: React.ReactNode;
  /**
   * Extra element to show inside LinkButton
   */
  extra?: React.ReactNode;
  /**
   * Position of the extra element
   */
  extraPosition?: "left" | "right";
  /**
   * Disables the LinkButton, similar to a disabled button
   */
  disabled?: boolean;
}

// eslint-disable-next-line max-lines-per-function
export const LinkButton = forwardRef<HTMLAnchorElement, LinkButtonProps>((props, ref) => {
  const { position, setPosition, updateCursor } = useCursor();
  const {
    href,
    extra,
    extraPosition = "right",
    size = "l",
    text,
    children,
    css,
    onClick,
    onFocus,
    disabled,
    ...rest
  } = props;

  const handleMouseDown: React.MouseEventHandler = useCallback(
    (evt) => updateCursor(evt),
    [updateCursor]
  );
  const handeMouseUp: React.MouseEventHandler = useCallback(() => setPosition(null), [setPosition]);

  const handleClick: React.MouseEventHandler<HTMLAnchorElement> = useCallback(
    (evt) => {
      if (disabled) {
        evt.preventDefault();
      }
      onClick?.(evt);
    },
    [disabled, onClick]
  );

  const handleFocus: React.FocusEventHandler<HTMLAnchorElement> = useCallback(
    (evt) => {
      if (disabled) {
        evt.currentTarget.blur();
      }
      onFocus?.(evt);
    },
    [disabled, onFocus]
  );

  if (text && children) {
    throw new Error(
      "Don't use `text` and `children` at the same time. `text` is deprecated use `children` instead!"
    );
  }

  return (
    <StyledLinkButton
      href={href}
      ref={ref}
      size={size}
      css={{
        ...css,
        flexDirection: extraPosition === "left" ? "row-reverse" : "row",
        "&::after": {
          display: position ? "block" : "none",
          top: position?.y,
          left: position?.x,
        },
      }}
      {...rest}
      data-disabled={disabled}
      onClick={handleClick}
      onFocus={handleFocus}
      onMouseDown={handleMouseDown}
      onMouseUp={handeMouseUp}
    >
      {children ?? text}
      {extra}
    </StyledLinkButton>
  );
});

LinkButton.displayName = "LinkButton";
