"use client";

import type { InputHTMLAttributes, KeyboardEvent } from "react";

type NumericPhoneInputProps = Omit<
  InputHTMLAttributes<HTMLInputElement>,
  "inputMode" | "maxLength" | "pattern" | "type"
>;

const allowedKeys = new Set([
  "Backspace",
  "Delete",
  "ArrowLeft",
  "ArrowRight",
  "ArrowUp",
  "ArrowDown",
  "End",
  "Home",
  "Tab",
]);

export function sanitizePhoneNumber(value: string) {
  return value.replace(/\D/g, "").slice(0, 10);
}

export default function NumericPhoneInput({
  onInput,
  onKeyDown,
  onPaste,
  ...props
}: NumericPhoneInputProps) {
  function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {
    onKeyDown?.(event);
    if (event.defaultPrevented || event.ctrlKey || event.metaKey || event.altKey) return;
    if (!allowedKeys.has(event.key) && !/^\d$/.test(event.key)) event.preventDefault();
  }

  return (
    <input
      {...props}
      suppressHydrationWarning
      inputMode="numeric"
      maxLength={10}
      pattern="[0-9]{10}"
      type="tel"
      onInput={(event) => {
        event.currentTarget.value = sanitizePhoneNumber(event.currentTarget.value);
        onInput?.(event);
      }}
      onKeyDown={handleKeyDown}
      onPaste={(event) => {
        onPaste?.(event);
        if (event.defaultPrevented) return;
        event.preventDefault();
        const input = event.currentTarget;
        const start = input.selectionStart ?? input.value.length;
        const end = input.selectionEnd ?? input.value.length;
        input.value = sanitizePhoneNumber(
          `${input.value.slice(0, start)}${event.clipboardData.getData("text")}${input.value.slice(end)}`,
        );
      }}
    />
  );
}
