import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from "react";
import { cx } from "../../lib/utils";
import { Spinner } from "./Spinner";

export type ButtonVariant = "default" | "primary" | "danger" | "success" | "warning" | "text";
export type ButtonSize = "small" | "default" | "large";

export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: ButtonVariant;
  size?: ButtonSize;
  loading?: boolean;
  icon?: ReactNode;
  block?: boolean;
  plain?: boolean;
}

const SIZE: Record<ButtonSize, string> = {
  small: "h-6 px-[11px] text-xs",
  default: "h-8 px-[15px] text-sm",
  large: "h-10 px-[19px] text-sm",
};

const SOLID: Record<string, string> = {
  primary:
    "border-transparent bg-[#0ea5e9] text-white hover:bg-[#38bdf8] active:bg-[#0284c7] ui-action-btn-primary disabled:hover:bg-[#0ea5e9]",
  danger:
    "border-transparent bg-[#f56c6c] text-white hover:bg-[#f78989] active:bg-[#dd6161] ui-action-btn disabled:hover:bg-[#f56c6c]",
  success:
    "border-transparent bg-[#67c23a] text-white hover:bg-[#85ce61] active:bg-[#5daf34] ui-action-btn disabled:hover:bg-[#67c23a]",
  warning:
    "border-transparent bg-[#e6a23c] text-white hover:bg-[#ebb563] active:bg-[#cf9236] ui-action-btn disabled:hover:bg-[#e6a23c]",
};

// Element Plus "plain" style: light-tint background with colored text + border,
// going solid on hover. Primary stays on the light-blue theme.
const PLAIN: Record<string, string> = {
  primary:
    "border-[#7dd3fc] bg-[#f0f9ff] text-[#0ea5e9] hover:border-[#0ea5e9] hover:bg-[#0ea5e9] hover:text-white active:bg-[#0284c7] ui-action-btn disabled:hover:border-[#7dd3fc] disabled:hover:bg-[#f0f9ff] disabled:hover:text-[#0ea5e9] dark:border-[#0ea5e9]/40 dark:bg-[#0ea5e9]/10 dark:text-[#7dd3fc] dark:hover:border-[#0ea5e9] dark:hover:bg-[#0ea5e9] dark:hover:text-white",
  danger:
    "border-[#f5b3b3] bg-[#fef0f0] text-[#f56c6c] hover:border-[#f56c6c] hover:bg-[#f56c6c] hover:text-white active:bg-[#dd6161] ui-action-btn disabled:hover:border-[#f5b3b3] disabled:hover:bg-[#fef0f0] disabled:hover:text-[#f56c6c] dark:border-[#f56c6c]/40 dark:bg-[#f56c6c]/10 dark:text-[#f78989] dark:hover:border-[#f56c6c] dark:hover:bg-[#f56c6c] dark:hover:text-white",
  success:
    "border-[#a9d68b] bg-[#f0f9eb] text-[#67c23a] hover:border-[#67c23a] hover:bg-[#67c23a] hover:text-white active:bg-[#5daf34] ui-action-btn disabled:hover:border-[#a9d68b] disabled:hover:bg-[#f0f9eb] disabled:hover:text-[#67c23a] dark:border-[#67c23a]/40 dark:bg-[#67c23a]/10 dark:text-[#85ce61] dark:hover:border-[#67c23a] dark:hover:bg-[#67c23a] dark:hover:text-white",
  warning:
    "border-[#f0c687] bg-[#fdf6ec] text-[#e6a23c] hover:border-[#e6a23c] hover:bg-[#e6a23c] hover:text-white active:bg-[#cf9236] ui-action-btn disabled:hover:border-[#f0c687] disabled:hover:bg-[#fdf6ec] disabled:hover:text-[#e6a23c] dark:border-[#e6a23c]/40 dark:bg-[#e6a23c]/10 dark:text-[#ebb563] dark:hover:border-[#e6a23c] dark:hover:bg-[#e6a23c] dark:hover:text-white",
};

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
  {
    variant = "default",
    size = "default",
    loading = false,
    icon,
    block = false,
    plain = false,
    className,
    children,
    disabled,
    type = "button",
    ...rest
  },
  ref,
) {
  const isText = variant === "text";
  const isDefault = variant === "default";
  const isDisabled = disabled || loading;

  const variantClass = isText
    ? "border-transparent bg-transparent text-[#0ea5e9] hover:bg-black/5 dark:hover:bg-white/10 shadow-none"
    : isDefault
      ? "border-[#dcdfe6] bg-white text-gray-700 hover:border-[#c6c8f0] hover:bg-[#f1f1fc] hover:text-[#0ea5e9] ui-action-btn dark:border-white/15 dark:bg-white/5 dark:text-gray-200 dark:hover:border-[#0ea5e9]/50 dark:hover:bg-white/10 dark:hover:text-[#7dd3fc]"
      : plain
        ? PLAIN[variant]
        : SOLID[variant];

  return (
    <button
      ref={ref}
      type={type}
      disabled={isDisabled}
      className={cx(
        "inline-flex select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-lg border font-medium outline-none transition-all duration-150",
        "focus-visible:ring-2 focus-visible:ring-[#0ea5e9]/50 focus-visible:ring-offset-1 dark:focus-visible:ring-offset-gray-950",
        "active:translate-y-px disabled:cursor-not-allowed disabled:opacity-60",
        SIZE[size],
        isText && "px-2 shadow-none",
        block && "w-full",
        variantClass,
        className,
      )}
      {...rest}
    >
      {loading ? <Spinner className="h-[1em] w-[1em]" /> : icon ? <span className="inline-flex shrink-0 items-center text-[1.1em]">{icon}</span> : null}
      {children ? <span className="inline-flex items-center gap-1.5">{children}</span> : null}
    </button>
  );
});
