import { useEffect, useRef, useState } from "react";
import { cn } from "~/utils/cn";
import { CopyButton } from "./CopyButton";

const variants = {
  "primary/small": {
    container:
      "flex items-center text-text-dimmed font-mono rounded border bg-background-hover text-xs transition hover:bg-background-raised focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
    input:
      "bg-transparent border-0 text-xs px-2 w-auto rounded-l h-6 leading-6 focus:ring-transparent",
    buttonVariant: "primary" as const,
    size: "small" as const,
    button: "rounded-l-none",
  },
  "secondary/small": {
    container:
      "flex items-center text-text-dimmed font-mono rounded border bg-background-hover text-xs transition hover:bg-background-raised focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
    input:
      "bg-transparent border-0 text-xs px-2 w-auto rounded-l h-6 leading-6 focus:ring-transparent",
    buttonVariant: "tertiary" as const,
    size: "small" as const,
    button: "rounded-l-none border-l border-grid-dimmed",
  },
  "tertiary/small": {
    container:
      "group/clipboard flex items-center text-text-dimmed font-mono rounded bg-transparent border border-transparent text-xs transition duration-150 hover:border-grid-bright focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
    input:
      "bg-transparent border-0 text-xs px-2 w-auto rounded-l h-6 leading-6 focus:ring-transparent",
    buttonVariant: "minimal" as const,
    size: "small" as const,
    button:
      "rounded-l-none border-l border-transparent transition group-hover/clipboard:border-grid-bright",
  },
  "primary/medium": {
    container:
      "flex items-center text-text-dimmed font-mono rounded border bg-background-hover text-sm transition hover:bg-background-raised focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
    input:
      "bg-transparent border-0 text-sm px-3 w-auto rounded-l h-8 leading-6 focus:ring-transparent",
    buttonVariant: "primary" as const,
    size: "medium" as const,
    button: "rounded-l-none",
  },
  "secondary/medium": {
    container:
      "flex items-center text-text-dimmed font-mono rounded bg-background-hover text-sm transition hover:bg-background-raised focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
    input:
      "bg-transparent border-0 text-sm px-3 w-auto rounded-l h-8 leading-6 focus:ring-transparent",
    buttonVariant: "tertiary" as const,
    size: "medium" as const,
    button: "rounded-l-none border-l border-grid-dimmed",
  },
  "tertiary/medium": {
    container:
      "group flex items-center text-text-dimmed font-mono rounded bg-transparent border border-transparent text-sm transition hover:border-grid-bright focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
    input:
      "bg-transparent border-0 text-sm px-3 w-auto rounded-l h-8 leading-6 focus:ring-transparent",
    buttonVariant: "minimal" as const,
    size: "medium" as const,
    button: "rounded-l-none border-l border-transparent transition group-hover:border-grid-bright",
  },
};

type ClipboardFieldProps = {
  value: string;
  secure?: boolean | string;
  variant: keyof typeof variants;
  className?: string;
  icon?: React.ReactNode;
  iconButton?: boolean;
  fullWidth?: boolean;
};

export function ClipboardField({
  value,
  secure = false,
  variant,
  className,
  icon,
  iconButton = false,
  fullWidth = true,
}: ClipboardFieldProps) {
  const [isSecure, setIsSecure] = useState(secure !== undefined && secure);
  const inputIcon = useRef<HTMLInputElement>(null);
  const { container, input, buttonVariant, button, size } = variants[variant];

  useEffect(() => {
    setIsSecure(secure !== undefined && secure);
  }, [secure]);

  return (
    <span className={cn(container, fullWidth ? "w-full" : "max-w-fit", className)}>
      {icon && (
        <span
          onClick={() => inputIcon.current && inputIcon.current.focus()}
          className="flex items-center pl-1"
        >
          {icon}
        </span>
      )}
      <input
        type="text"
        ref={inputIcon}
        value={isSecure ? (typeof secure === "string" ? secure : "••••••••••••••••") : value}
        readOnly={true}
        className={cn(
          "shrink grow select-all overflow-x-auto",
          fullWidth ? "w-full" : "max-w-fit",
          input
        )}
        onFocus={(e) => {
          if (secure) {
            setIsSecure(false);
          }
          e.currentTarget.select();
        }}
        onBlur={() => {
          if (secure) {
            setIsSecure(true);
          }
        }}
      />
      <CopyButton
        value={value}
        variant={iconButton ? "icon" : "button"}
        buttonVariant={buttonVariant}
        size={size}
        buttonClassName={button}
        showTooltip={false}
      />
    </span>
  );
}
