"use client";

import { useEffect, useRef, type KeyboardEvent, type ClipboardEvent } from "react";
import { cn } from "@/lib/utils";

interface Props {
  value: string;
  onChange: (v: string) => void;
  length?: number;
  ariaLabel: string;
  autoFocus?: boolean;
  invalid?: boolean;
}

export function OtpInput({
  value,
  onChange,
  length = 6,
  ariaLabel,
  autoFocus = false,
  invalid = false,
}: Props) {
  const refs = useRef<Array<HTMLInputElement | null>>([]);

  useEffect(() => {
    if (autoFocus) refs.current[0]?.focus();
  }, [autoFocus]);

  function setDigit(i: number, raw: string) {
    const digit = raw.replace(/\D/g, "").slice(-1);
    const chars = value.padEnd(length, " ").split("");
    chars[i] = digit || " ";
    const next = chars.join("").trimEnd();
    onChange(next);
    if (digit && i < length - 1) refs.current[i + 1]?.focus();
  }

  function onKey(e: KeyboardEvent<HTMLInputElement>, i: number) {
    if (e.key === "Backspace") {
      const chars = value.padEnd(length, " ").split("");
      if (chars[i] && chars[i] !== " ") {
        chars[i] = " ";
        onChange(chars.join("").trimEnd());
      } else if (i > 0) {
        refs.current[i - 1]?.focus();
        const prev = chars.slice();
        prev[i - 1] = " ";
        onChange(prev.join("").trimEnd());
      }
    } else if (e.key === "ArrowLeft" && i > 0) {
      refs.current[i - 1]?.focus();
    } else if (e.key === "ArrowRight" && i < length - 1) {
      refs.current[i + 1]?.focus();
    }
  }

  function onPaste(e: ClipboardEvent<HTMLInputElement>) {
    const txt = e.clipboardData.getData("text").replace(/\D/g, "").slice(0, length);
    if (!txt) return;
    e.preventDefault();
    onChange(txt);
    const focusIdx = Math.min(txt.length, length - 1);
    refs.current[focusIdx]?.focus();
  }

  return (
    <div
      className="flex items-center justify-center gap-2 sm:gap-3"
      role="group"
      aria-label={ariaLabel}
    >
      {Array.from({ length }).map((_, i) => {
        const ch = value[i] ?? "";
        return (
          <input
            key={i}
            ref={(el) => {
              refs.current[i] = el;
            }}
            type="text"
            inputMode="numeric"
            autoComplete="one-time-code"
            maxLength={1}
            aria-label={`${ariaLabel} ${i + 1}`}
            aria-invalid={invalid || undefined}
            value={ch.trim()}
            onChange={(e) => setDigit(i, e.target.value)}
            onKeyDown={(e) => onKey(e, i)}
            onPaste={onPaste}
            onFocus={(e) => e.currentTarget.select()}
            className={cn(
              "h-12 w-10 rounded-2xl border bg-white text-center text-lg font-bold tabular-nums text-slate-900 outline-none transition focus:border-brand-500 focus:shadow-glow-sm sm:h-14 sm:w-12 sm:text-xl",
              invalid
                ? "border-rose-300 dark:border-rose-400/40"
                : "border-slate-200 dark:border-slate-700",
              "dark:bg-slate-900 dark:text-white",
            )}
          />
        );
      })}
    </div>
  );
}
