"use client";

import * as React from "react";
import { motion } from "framer-motion";
import { ArrowRight } from "lucide-react";
import Link from "next/link";

interface ButtonProps {
  href: string;
  children: React.ReactNode;
  variant?: "primary" | "outline" | "ghost";
  size?: "normal" | "large";
  className?: string;
  showArrow?: boolean;
  onClick?: (e: React.MouseEvent<any>) => void;
  [key: string]: any;
}

/**
 * Premium Button: Pill-shaped, binary-accent hover effect, unified design.
 *
 * On hover:
 * - A stream of binary characters scrolls across the button background
 * - Primary: white binary on dark bg
 * - Outline: blue binary on transparent bg
 * - Subtle, fast, and satisfying
 */
export const Button: React.FC<ButtonProps> = ({
  href,
  children,
  variant = "primary",
  size = "normal",
  className = "",
  showArrow = true,
  onClick,
  ...props
}) => {
  const [hovered, setHovered] = React.useState(false);
  const [displayText, setDisplayText] = React.useState<string | null>(null);
  const contentRef = React.useRef<HTMLSpanElement>(null);

  // Binary scramble on hover
  React.useEffect(() => {
    if (!hovered) {
      setDisplayText(null);
      return;
    }
    const original = contentRef.current?.textContent || "";
    if (!original) return;
    const chars = original.split("");
    const total = 20;
    let frame = 0;
    const iv = setInterval(() => {
      frame++;
      const s = chars.map((c, i) => {
        if (c === " ") return " ";
        const settle = (frame / total) * chars.length;
        if (i < settle) return c;
        return Math.random() > 0.5 ? "1" : "0";
      });
      setDisplayText(s.join(""));
      if (frame >= total) {
        setDisplayText(null);
        clearInterval(iv);
      }
    }, 1000 / 60);
    return () => clearInterval(iv);
  }, [hovered]);

  const [binaryStr, setBinaryStr] = React.useState(
    "0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1",
  );

  React.useEffect(() => {
    setBinaryStr(
      Array.from({ length: 60 }, () => (Math.random() > 0.5 ? "0" : "1")).join(
        " ",
      ),
    );
  }, []);

  const base =
    "relative inline-flex items-center justify-center gap-3 overflow-hidden rounded-full font-bold uppercase tracking-[0.15em] transition-all duration-300 group cursor-pointer";

  const sizes: Record<string, string> = {
    normal: "px-8 py-4 text-[10px]",
    large: "px-10 py-5 text-[11px]",
  };

  const variants: Record<string, string> = {
    primary:
      "bg-slate-900 text-white hover:shadow-xl hover:shadow-slate-900/20 hover:-translate-y-0.5",
    outline:
      "border border-slate-200 bg-transparent text-slate-900 hover:border-slate-400 hover:-translate-y-0.5",
    ghost: "bg-transparent text-slate-500 hover:text-slate-900",
  };

  // Binary stream overlay colors by variant
  const binaryColor =
    variant === "primary"
      ? "rgba(255,255,255,0.06)"
      : variant === "outline"
        ? "rgba(59,130,246,0.08)"
        : "rgba(148,163,184,0.06)";

  const inner = (
    <motion.span
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      className={`${base} ${sizes[size]} ${variants[variant]} ${className}`}
    >
      {/* Binary stream hover overlay */}
      <span
        className="absolute inset-0 flex items-center pointer-events-none overflow-hidden"
        style={{ opacity: hovered ? 1 : 0, transition: "opacity 0.3s ease" }}
      >
        <motion.span
          className="whitespace-nowrap font-mono text-[8px] tracking-[0.3em] select-none"
          style={{ color: binaryColor }}
          animate={hovered ? { x: [0, -200] } : { x: 0 }}
          transition={
            hovered ? { duration: 3, repeat: Infinity, ease: "linear" } : {}
          }
        >
          {binaryStr}&nbsp;{binaryStr}
        </motion.span>
      </span>

      {/* Shimmer line on hover (top edge) */}
      <span
        className="absolute top-0 left-0 right-0 h-px pointer-events-none"
        style={{
          opacity: hovered ? 1 : 0,
          transition: "opacity 0.5s ease",
          background:
            variant === "primary"
              ? "linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent)"
              : "linear-gradient(90deg, transparent, rgba(59,130,246,0.15), transparent)",
        }}
      />

      {/* Content */}
      <span
        className="relative z-10 flex items-center gap-3"
        style={{ fontVariantNumeric: "tabular-nums" }}
      >
        <span ref={contentRef}>{displayText ?? children}</span>
        {showArrow && (
          <ArrowRight className="w-3.5 h-3.5 group-hover:translate-x-1 transition-transform duration-300" />
        )}
      </span>
    </motion.span>
  );

  if (href.startsWith("#")) {
    return (
      <a
        href={href}
        onClick={(e) => {
          if (onClick) onClick(e);
          e.preventDefault();
          document.querySelector(href)?.scrollIntoView({ behavior: "smooth" });
        }}
        {...props}
      >
        {inner}
      </a>
    );
  }

  return (
    <Link href={href} onClick={onClick} {...props}>
      {inner}
    </Link>
  );
};
