"use client";

import { motion } from "motion/react";
import { useEffect, useState } from "react";
import { Link } from "@/i18n/navigation";
import { cn } from "@/lib/utils";

type Direction = "TOP" | "LEFT" | "BOTTOM" | "RIGHT";

const directions: Direction[] = ["TOP", "LEFT", "BOTTOM", "RIGHT"];

const movingMap: Record<Direction, string> = {
  TOP: "radial-gradient(20.7% 50% at 50% 0%, #ffffff 0%, rgba(255, 255, 255, 0) 100%)",
  LEFT: "radial-gradient(16.6% 43.1% at 0% 50%, #ffffff 0%, rgba(255, 255, 255, 0) 100%)",
  BOTTOM:
    "radial-gradient(20.7% 50% at 50% 100%, #ffffff 0%, rgba(255, 255, 255, 0) 100%)",
  RIGHT:
    "radial-gradient(16.2% 41.2% at 100% 50%, #ffffff 0%, rgba(255, 255, 255, 0) 100%)",
};

// Brand color (#fd105e) glow on hover
const highlight =
  "radial-gradient(75% 181.15942028985506% at 50% 50%, #fd105e 0%, rgba(253, 16, 94, 0) 100%)";

type HoverBorderGradientProps = React.PropsWithChildren<
  {
    as?: React.ElementType;
    href?: string;
    containerClassName?: string;
    className?: string;
    duration?: number;
    clockwise?: boolean;
  } & React.HTMLAttributes<HTMLElement>
>;

export function HoverBorderGradient({
  children,
  containerClassName,
  className,
  as,
  href,
  duration = 1,
  clockwise = true,
  ...props
}: HoverBorderGradientProps) {
  // Polymorphic component — Tag may be a custom component, the i18n Link, or
  // a native button. The unions of element-specific event handlers cause TS
  // to narrow spread props to a never intersection; the runtime is safe.
  // biome-ignore lint/suspicious/noExplicitAny: dynamic polymorphic tag
  const Tag: any = as ?? (href ? Link : "button");

  const [hovered, setHovered] = useState(false);
  const [direction, setDirection] = useState<Direction>("TOP");

  useEffect(() => {
    if (hovered) {
      return;
    }
    const interval = setInterval(() => {
      setDirection((prev) => {
        const i = directions.indexOf(prev);
        const next = clockwise
          ? (i - 1 + directions.length) % directions.length
          : (i + 1) % directions.length;
        return directions[next];
      });
    }, duration * 1000);
    return () => clearInterval(interval);
  }, [hovered, clockwise, duration]);

  return (
    <Tag
      {...(href ? { href } : {})}
      className={cn(
        "relative flex h-min w-fit flex-col flex-nowrap content-center items-center justify-center gap-10 overflow-visible rounded-full border border-white/10 bg-white/5 decoration-clone p-px transition duration-500 hover:bg-white/10",
        containerClassName
      )}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      {...props}
    >
      <div
        className={cn(
          "z-10 w-auto rounded-[inherit] bg-black px-4 py-2 text-white",
          className
        )}
      >
        {children}
      </div>
      <motion.div
        animate={{
          background: hovered
            ? [movingMap[direction], highlight]
            : movingMap[direction],
        }}
        className="absolute inset-0 z-0 flex-none overflow-hidden rounded-[inherit]"
        initial={{ background: movingMap[direction] }}
        style={{
          filter: "blur(2px)",
          position: "absolute",
          width: "100%",
          height: "100%",
        }}
        transition={{ ease: "linear", duration }}
      />
      <div className="absolute inset-[2px] z-1 flex-none rounded-[100px] bg-black" />
    </Tag>
  );
}
