"use client";

import { Input } from "@/components/ui/input";
import MultiSelect from "./multiSelect";
import React, { useEffect, useState } from "react";

interface LabeledInputProps {
  id?: string;
  name: string;
  label?: string;
  icon?: React.ReactNode;
  required?: boolean;
  type?: string;
  placeholder?: string;
  inputClassName?: string;
  className?: string;
  options?: { label: string; value: string, disabled?: boolean }[];
  radioDirection?: 'row' | 'column';
  value?: string;
  onChange?: (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => void;
  multiValue?: string[];
  onMultiChange?: (values: string[]) => void;
  dir?: 'rtl' | 'ltr';
  formatThousands?: boolean;
}

export default function Field({
  id,
  name,
  label,
  icon,
  required,
  type = "text",
  placeholder,
  inputClassName = "",
  className = "",
  options = [],
  radioDirection = 'row',
  value,
  onChange,
  multiValue,
  onMultiChange,
  dir,
  formatThousands = true,
}: LabeledInputProps) {
  const inputId = id || name;
  const [displayValue, setDisplayValue] = useState<string>(typeof value === 'string' ? value : "");

  const formatWithThousands = (raw: string) => {
    const digitsOnly = raw.replace(/\D/g, "");
    if (!digitsOnly) return "";
    return digitsOnly.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  };

  useEffect(() => {
    if (type === "number") {
      const v = typeof value === 'string' ? value : "";
      if (formatThousands) {
        setDisplayValue(formatWithThousands(v));
      } else {
        setDisplayValue(v.replace(/\D/g, ""));
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [value, type, formatThousands]);

  const handleNumberChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const raw = e.target.value;
    const digitsOnly = raw.replace(/\D/g, "");
    const formatted = formatThousands ? formatWithThousands(digitsOnly) : digitsOnly;
    setDisplayValue(formatted);
    if (onChange) {
      const forwarded = {
        ...e,
        target: {
          ...(e.target as any),
          name,
          value: digitsOnly,
        },
      } as unknown as React.ChangeEvent<HTMLInputElement>;
      onChange(forwarded as unknown as React.ChangeEvent<HTMLInputElement>);
    }
  };
  return (
    <div className={`relative ${className}`}>
      {type === "radio" ? null : (
        <label
          htmlFor={inputId}
          className="px-2 absolute right-3 -top-[25%] bg-white block text-sm text-gray-700 z-1"
        >
          {label}
          {required && label ? <span className="text-red-500">{'    *'}</span> : null}
        </label>
      )}
      {type === "select" ? (
        <Input
          as="select"
          id={inputId}
          name={name}
          required={required}
          className={`text-sm placeholder:text-[#90A1B9] ${inputClassName}`}
          {...(typeof value === "string" ? { value } : { defaultValue: "" })}
          onChange={onChange}
          dir={dir}
        >
          {placeholder ? (
            <option value="" disabled>
              {placeholder}
            </option>
          ) : null}
          {options.map((opt) => (
            <option key={opt.value} value={opt.value} disabled={opt.disabled}>
              {opt.label}
            </option>
          ))}
        </Input>
      ) : type === 'multi-select' ? (
        <MultiSelect name={name} options={options} value={multiValue || []} onChange={onMultiChange || (() => { })} placeholder={placeholder} />
      ) : type === "radio" ? (
        <div className="bg-[#F1F5F9] p-4 rounded-md">
          {label}
          <div className={`mt-4 flex gap-5 ${radioDirection === 'row' ? 'flex-row' : 'flex-col'}`}>
            {options.map((option) => (
              <div key={option.value} className="flex-1 flex items-center gap-2">
                <input
                  type="radio"
                  className="w-4 h-4 accent-[#05222D]"
                  id={`${name}-${option.value}`}
                  name={name}
                  value={option.value}
                  // Use controlled mode only when a value+onChange pair are provided
                  {...(value !== undefined && onChange
                    ? { checked: value === option.value, onChange }
                    : { defaultChecked: false }
                  )}
                  required={required}
                />
                <label
                  htmlFor={`${name}-${option.value}`}
                  className="text-[#1D293D]"
                >
                  {option.label}
                </label>
              </div>
            ))}
          </div>
        </div>
      ) : (
        <Input
          id={inputId}
          name={name}
          type={type === "number" ? "text" : type}
          placeholder={placeholder}
          required={required}
          className={`text-sm placeholder:text-[#90A1B9] ${inputClassName}`}
          icon={icon}
          inputMode={type === "number" ? "numeric" : (type === "tel" ? "tel" : undefined)}
          pattern={type === "tel" ? "^[+0-9]*$" : undefined}
          dir={dir}
          onKeyDown={(e) => {
            if (type === "number") {
              const allowed = [
                "Backspace",
                "Tab",
                "ArrowLeft",
                "ArrowRight",
                "Delete",
                "Home",
                "End",
              ];
              if (
                !/[0-9]/.test(e.key) &&
                !allowed.includes(e.key)
              ) {
                e.preventDefault();
              }
            } else if (type === "tel") {
              const allowed = [
                "Backspace",
                "Tab",
                "ArrowLeft",
                "ArrowRight",
                "Delete",
                "Home",
                "End",
              ];
              if (
                !/[0-9+]/.test(e.key) &&
                !allowed.includes(e.key)
              ) {
                e.preventDefault();
              }
            }
          }}
          onInput={(e) => {
            if (type === "number" && !formatThousands) {
              const target = e.currentTarget as HTMLInputElement;
              const filtered = target.value.replace(/\D/g, "");
              if (filtered !== target.value) {
                target.value = filtered;
              }
              if (filtered !== displayValue) {
                setDisplayValue(filtered);
              }
            } else if (type === "tel") {
              const target = e.currentTarget as HTMLInputElement;
              const filtered = target.value.replace(/[^0-9+]/g, "");
              if (filtered !== target.value) {
                target.value = filtered;
              }
            }
          }}
          value={type === "number" ? displayValue : undefined}
          onChange={type === "number" ? handleNumberChange : onChange}
        />
      )}
    </div>
  );
}
