"use client";

import React from "react";
import { cn } from "@/utils/cn";
import { LucideIcon } from "lucide-react";

interface SlateButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  icon?:
    | LucideIcon
    | React.ComponentType<{
        className?: string;
        isHovered?: boolean;
        isOpen?: boolean;
      }>
    | React.ReactNode;
  iconPosition?: "left" | "right";
  children: React.ReactNode;
  size?: "sm" | "md" | "lg";
  fullWidth?: boolean;
  isLoading?: boolean;
  isOpen?: boolean;
}

export const SlateButton = React.forwardRef<
  HTMLButtonElement,
  SlateButtonProps
>(
  (
    {
      icon: Icon,
      iconPosition = "left",
      children,
      className,
      size = "md",
      fullWidth = false,
      isLoading = false,
      isOpen = false,
      disabled,
      ...props
    },
    ref,
  ) => {
    const [isHovered, setIsHovered] = React.useState(false);

    const sizeClasses = {
      sm: "h-32 px-12 text-body-small gap-6",
      md: "h-40 px-16 text-body-medium gap-8",
      lg: "h-48 px-24 text-body-large gap-10",
    };

    const iconSizes = {
      sm: "w-14 h-14",
      md: "w-16 h-16",
      lg: "w-20 h-20",
    };

    return (
      <button
        ref={ref}
        className={cn(
          // Base styles
          "inline-flex items-center justify-center rounded-12  transition-all",
          // Colors
          "bg-black-alpha-4 text-accent-black",
          "hover:bg-black-alpha-6",
          "active:scale-[0.98]",
          // Border
          // "border-0",
          // Size
          sizeClasses[size],
          // States
          disabled && "opacity-50 cursor-not-allowed",
          isLoading && "cursor-wait",
          // Full width
          fullWidth && "w-full",
          className,
        )}
        disabled={disabled || isLoading}
        onMouseEnter={() => setIsHovered(true)}
        onMouseLeave={() => setIsHovered(false)}
        {...props}
      >
        {isLoading ? (
          <div className={cn("animate-spin rounded-full", iconSizes[size])} />
        ) : (
          <>
            {Icon &&
              iconPosition === "left" &&
              (React.isValidElement(Icon) ? (
                Icon
              ) : (
                //@ts-expect-error - Icon component type allows JSX element
                <Icon
                  className={cn(iconSizes[size], "flex-shrink-0")}
                  isHovered={isHovered}
                  isOpen={isOpen}
                />
              ))}
            {children}
            {Icon &&
              iconPosition === "right" &&
              (React.isValidElement(Icon) ? (
                Icon
              ) : (
                //@ts-expect-error - Icon component type allows JSX element
                <Icon
                  className={cn(iconSizes[size], "flex-shrink-0")}
                  isHovered={isHovered}
                  isOpen={isOpen}
                />
              ))}
          </>
        )}
      </button>
    );
  },
);

SlateButton.displayName = "SlateButton";
