import Link from "next/link";
import type { ButtonHTMLAttributes, ReactNode } from "react";

import { cn } from "@/lib/utils";

/**
 * Button primitive.
 *
 * Renders an `<a>` when `href` is supplied, a `<button>` otherwise, so
 * navigation stays a real link (middle-click, SEO, prefetch) while in-page
 * actions stay real buttons.
 */
export type ButtonVariant = "primary" | "secondary" | "ghost" | "outline" | "danger" | "brand";
export type ButtonSize = "sm" | "md" | "lg" | "icon";

const VARIANTS: Record<ButtonVariant, string> = {
  primary:
    "bg-white text-black hover:bg-white/90 active:bg-white/80 shadow-pill disabled:bg-white/40",
  secondary:
    "bg-surface-2/85 text-ink hover:bg-surface-3/90 backdrop-blur-md border border-line",
  ghost: "bg-transparent text-ink-soft hover:text-ink hover:bg-white/8 border border-transparent",
  outline: "bg-transparent text-ink border border-line-strong hover:bg-white/8 hover:border-white/30",
  danger: "bg-brand-600 text-white hover:bg-brand-500 active:bg-brand-700 shadow-pill",
  brand:
    "bg-linear-to-r from-brand-600 to-brand-500 text-white hover:from-brand-500 hover:to-brand-400 shadow-[0_10px_30px_-10px_rgba(244,63,94,0.7)]",
};

const SIZES: Record<ButtonSize, string> = {
  sm: "h-9 px-4 text-[13px] gap-1.5 rounded-pill",
  md: "h-11 px-5 text-sm gap-2 rounded-pill",
  lg: "h-[52px] px-7 text-[15px] gap-2.5 rounded-pill",
  icon: "h-10 w-10 rounded-full",
};

export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: ButtonVariant;
  size?: ButtonSize;
  href?: string;
  external?: boolean;
  loading?: boolean;
  children?: ReactNode;
}

export function Button({
  variant = "primary",
  size = "md",
  href,
  external,
  loading = false,
  className,
  children,
  disabled,
  ...rest
}: ButtonProps) {
  const classes = cn(
    "inline-flex items-center justify-center font-semibold tracking-[-0.01em] whitespace-nowrap",
    "transition-[transform,background-color,color,box-shadow,border-color] duration-300 ease-[cubic-bezier(0.25,0.46,0.45,0.94)]",
    "active:scale-[0.97] disabled:pointer-events-none disabled:opacity-55",
    VARIANTS[variant],
    SIZES[size],
    className,
  );

  if (href) {
    if (external) {
      return (
        <a
          href={href}
          className={classes}
          target="_blank"
          rel="noopener noreferrer"
          {...(rest as Record<string, unknown>)}
        >
          {children}
        </a>
      );
    }
    return (
      <Link href={href} className={classes} {...(rest as Record<string, unknown>)}>
        {children}
      </Link>
    );
  }

  return (
    <button className={classes} disabled={disabled || loading} {...rest}>
      {loading ? <Spinner /> : null}
      {children}
    </button>
  );
}

export function Spinner({ className }: { className?: string }) {
  return (
    <span
      aria-hidden
      className={cn(
        "inline-block h-4 w-4 rounded-full border-2 border-current/25 border-t-current animate-spin-slow",
        className,
      )}
    />
  );
}
