import Link from "next/link";
import { cn } from "@/lib/utils";
import type { ReactNode } from "react";

type Variant = "solid" | "outline" | "ghost";

const BASE =
  "group relative inline-flex items-center justify-center gap-2.5 overflow-hidden rounded-full px-6 py-3 text-sm transition-colors duration-300";

const VARIANTS: Record<Variant, string> = {
  solid: "bg-[var(--thread)] text-[var(--ink)] hover:text-[var(--ink)]",
  outline:
    "border border-[var(--rule)] text-[var(--cotton)] hover:border-[var(--thread)]",
  ghost: "text-[var(--cotton)] hover:text-[var(--thread)]",
};

interface Props {
  href: string;
  children: ReactNode;
  variant?: Variant;
  className?: string;
  external?: boolean;
}

/**
 * Primary call to action. The hover state sweeps a shuttle of colour across the
 * button, borrowing the motion of a weft carrier crossing a loom.
 */
export function Button({
  href,
  children,
  variant = "solid",
  className,
  external = false,
}: Props) {
  const inner = (
    <>
      {variant === "outline" ? (
        <span className="absolute inset-0 -z-10 translate-y-full bg-[var(--thread)] transition-transform duration-500 ease-[cubic-bezier(0.16,1,0.3,1)] group-hover:translate-y-0" />
      ) : null}
      <span
        className={cn(
          "relative z-10",
          variant === "outline" &&
            "transition-colors duration-300 group-hover:text-[var(--ink)]",
        )}
      >
        {children}
      </span>
      <span
        aria-hidden="true"
        className={cn(
          "relative z-10 transition-transform duration-500 ease-[cubic-bezier(0.16,1,0.3,1)] group-hover:translate-x-1",
          variant === "outline" &&
            "transition-colors group-hover:text-[var(--ink)]",
        )}
      >
        &rarr;
      </span>
    </>
  );

  const classes = cn(BASE, VARIANTS[variant], className);

  if (external) {
    return (
      <a href={href} className={classes} target="_blank" rel="noreferrer noopener">
        {inner}
      </a>
    );
  }

  return (
    <Link href={href} className={classes}>
      {inner}
    </Link>
  );
}
