import clsx from "clsx";
import { MouseEventHandler, ReactNode } from "react";
import { NavLink, NavLinkProps } from "react-router";

export interface IFancyLinkProps extends IBaseLinkProps {
  isNoop?: boolean;
}

interface IDownloadLinkProps extends IBaseLinkProps {
  fileName?: string;
}

interface IKemonoLinkProps
  extends Omit<IBaseLinkProps, "className">,
    Pick<NavLinkProps, "end" | "className" | "style"> {
  isNoop?: boolean;
}

interface ILocalLinkProps extends Omit<IBaseLinkProps, "url"> {
  id: string;
}

interface IEmailLinkProps extends Omit<IBaseLinkProps, "url"> {
  email: string;
}

interface ILinkButtonProps
  extends Omit<IBaseLinkProps, "className">,
    Pick<NavLinkProps, "end" | "className"> {
  isNoop?: boolean;
}

interface IBaseLinkProps {
  url: string;
  className?: string;
  children?: ReactNode;
  onClick?: MouseEventHandler<HTMLAnchorElement>;
}

export function FancyLink({
  url,
  isNoop = true,
  className,
  children,
}: IFancyLinkProps) {
  return (
    <a
      className={clsx("fancy-link", className)}
      href={url}
      target={!isNoop ? undefined : "_blank"}
      rel={!isNoop ? undefined : "noopener noreferrer"}
    >
      {children ?? url}
    </a>
  );
}

export function DownloadLink({
  url,
  fileName = url,
  className,
  children,
}: IDownloadLinkProps) {
  return (
    <a
      className={clsx("fancy-link", "fancy-link--download", className)}
      href={url}
      download={fileName}
    >
      {children ?? url}
    </a>
  );
}

export function KemonoLink({
  url,
  isNoop,
  className,
  end,
  style,
  children,
  ...props
}: IKemonoLinkProps) {
  return (
    <NavLink
      className={(...args) =>
        clsx(
          "fancy-link",
          "fancy-link--kemono",
          typeof className === "function" ? className(...args) : className
        )
      }
      to={url}
      end={end}
      style={style}
      {...props}
      target={!isNoop ? undefined : "_blank"}
    >
      {children ?? url}
    </NavLink>
  );
}

export function LocalLink({ id, className, children }: ILocalLinkProps) {
  return (
    <a
      className={clsx("fancy-link", "fancy-link--local", className)}
      href={`#${id}`}
    >
      {children ?? id}
    </a>
  );
}

export function EmailLink({ email, className, children }: IEmailLinkProps) {
  return (
    <a
      className={clsx("fancy-link", "fancy-link--email", className)}
      href={`mailto:${email}`}
      target="_blank"
      rel="noopener noreferrer"
    >
      {children ?? email}
    </a>
  );
}

export function LinkButton({
  url,
  isNoop,
  className,
  end,
  children,
}: ILinkButtonProps) {
  return (
    <NavLink
      className={(...args) =>
        clsx(
          "fancy-link",
          "fancy-link--button",
          typeof className === "function" ? className(...args) : className
        )
      }
      to={url}
      end={end}
      target={!isNoop ? undefined : "_blank"}
      rel={!isNoop ? undefined : "noopener noreferrer"}
    >
      {children ?? url}
    </NavLink>
  );
}
