"use client";

import * as React from "react";
import { useEffect, useRef, useState } from "react";
import { Eye, EyeOff } from "lucide-react";
import { useLocale } from "next-intl";

import { cn } from "@/lib/utils";

function Input({
  className,
  type,
  required,
  placeholder,
  ...props
}: React.ComponentProps<"input">) {
  const inputRef = useRef<HTMLInputElement>(null);
  const asteriskRef = useRef<HTMLSpanElement>(null);
  const [hasValue, setHasValue] = useState(false);
  const [showPassword, setShowPassword] = useState(false);
  const locale = useLocale();
  const isRTL = locale === "ar";
  const isPassword = type === "password";

  useEffect(() => {
    const input = inputRef.current;
    if (!input || !required || !asteriskRef.current) return;

    const updateAsteriskPosition = () => {
      if (!inputRef.current || !asteriskRef.current) return;

      const inputEl = inputRef.current;
      const asterisk = asteriskRef.current;

      // Wait for fonts to load and input to be fully rendered
      if (inputEl.offsetWidth === 0) {
        requestAnimationFrame(updateAsteriskPosition);
        return;
      }

      // Create a temporary span to measure placeholder text width
      const tempSpan = document.createElement("span");
      tempSpan.style.visibility = "hidden";
      tempSpan.style.position = "absolute";
      tempSpan.style.whiteSpace = "nowrap";
      tempSpan.style.fontSize = window.getComputedStyle(inputEl).fontSize;
      tempSpan.style.fontFamily = window.getComputedStyle(inputEl).fontFamily;
      tempSpan.style.fontWeight = window.getComputedStyle(inputEl).fontWeight;
      tempSpan.textContent = placeholder || "";
      document.body.appendChild(tempSpan);

      const placeholderWidth = tempSpan.offsetWidth;
      document.body.removeChild(tempSpan);

      // Get input padding and border
      const computedStyle = window.getComputedStyle(inputEl);
      const paddingRight = parseFloat(computedStyle.paddingRight);
      const paddingLeft = parseFloat(computedStyle.paddingLeft);
      const borderRight = parseFloat(computedStyle.borderRightWidth);
      const borderLeft = parseFloat(computedStyle.borderLeftWidth);

      // Position asterisk after placeholder text
      const currentIsRTL = document.documentElement.dir === "rtl";
      if (currentIsRTL) {
        // In RTL, text starts from right, so asterisk should be on the left after text
        const inputWidth = inputEl.offsetWidth;
        const asteriskPosition =
          inputWidth - paddingRight - borderRight - placeholderWidth - 8; // 8px spacing
        asterisk.style.left = `${asteriskPosition}px`;
        asterisk.style.right = "auto";
      } else {
        // In LTR, text starts from left, so asterisk should be on the right after text
        const asteriskPosition =
          paddingLeft + borderLeft + placeholderWidth + 8; // 8px spacing
        asterisk.style.left = `${asteriskPosition}px`;
        asterisk.style.right = "auto";
      }
    };

    const handleInput = () => {
      setHasValue(input.value.length > 0);
      updateAsteriskPosition();
    };

    // Use requestAnimationFrame to ensure DOM is ready
    requestAnimationFrame(() => {
      updateAsteriskPosition();
    });

    // Also update after fonts load
    if (document.fonts && document.fonts.ready) {
      document.fonts.ready.then(() => {
        updateAsteriskPosition();
      });
    }

    window.addEventListener("resize", updateAsteriskPosition);
    input.addEventListener("input", handleInput);
    input.addEventListener("focus", updateAsteriskPosition);
    input.addEventListener("blur", updateAsteriskPosition);

    return () => {
      window.removeEventListener("resize", updateAsteriskPosition);
      input.removeEventListener("input", handleInput);
      input.removeEventListener("focus", updateAsteriskPosition);
      input.removeEventListener("blur", updateAsteriskPosition);
    };
  }, [placeholder, required]);

  return (
    <div className="relative">
      <input
        ref={inputRef}
        type={isPassword && showPassword ? "text" : type}
        data-slot="input"
        required={required}
        placeholder={placeholder}
        className={cn(
          "bg-white text-text-main placeholder:text-gray-darker border-primary-main/30 w-full min-w-0 rounded-[8px] border p-3 text-base shadow-xs transition-[color,box-shadow,border-color] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
          "focus-visible:border-primary-main focus-visible:ring-primary-main/20 focus-visible:ring-[3px]",
          "aria-invalid:ring-destructive/20 aria-invalid:border-destructive",
          isPassword
            ? isRTL
              ? "pr-6 pl-10"
              : "pl-6 pr-10"
            : required
            ? isRTL
              ? "pr-6"
              : "pl-6"
            : "",
          className
        )}
        suppressHydrationWarning
        {...props}
      />
      {required && !hasValue && (
        <span
          ref={asteriskRef}
          className="absolute top-1/2 -translate-y-1/2 text-red-500 pointer-events-none text-sm opacity-60"
          suppressHydrationWarning
        >
          *
        </span>
      )}
      {isPassword && (
        <button
          type="button"
          onClick={() => setShowPassword(!showPassword)}
          className={`absolute top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700 transition-colors ${
            isRTL ? "left-3" : "right-3"
          }`}
          suppressHydrationWarning
          aria-label={showPassword ? "إخفاء كلمة المرور" : "إظهار كلمة المرور"}
        >
          {showPassword ? (
            <EyeOff className="w-5 h-5" />
          ) : (
            <Eye className="w-5 h-5" />
          )}
        </button>
      )}
    </div>
  );
}

export { Input };
