"use client";

import * as React from "react";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";

type InputOwnProps = Omit<
  React.ComponentPropsWithoutRef<"input">,
  "name" | "value" | "onChange" | "onBlur" | "form" | "type" | "inputMode"
>;

interface FormFieldProps extends InputOwnProps {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  form: any;
  name: string;
  label: string;
  type?: React.HTMLInputTypeAttribute;
  required?: boolean;
  requiredMessage?: string;
  className?: string;
  currency?: boolean;
}

const formatRp = (num: number) =>
  new Intl.NumberFormat("id-ID").format(num);


export const FormField = React.forwardRef<HTMLInputElement, FormFieldProps>(
  function FormField(
    { form, name, label, type = "text", required, requiredMessage, disabled, className, currency = false, ...inputProps },
    ref
  ) {
    const validators = required
      ? {
          onSubmit: ({ value }: { value: unknown }) =>
            !value && value !== 0 ? requiredMessage || `${label} wajib diisi` : undefined,
        }
      : undefined;

    return (
      <form.Field name={name} validators={validators}>
        {(field: any) => (
          <div className={className || "space-y-0.5"}>
            <Label htmlFor={name}>{label}</Label>
            {currency ? (
              <CurrencyInput
                ref={ref}
                id={name}
                value={field.state.value ?? 0}
                onChange={(num) => field.handleChange(num)}
                onBlur={field.handleBlur}
                disabled={disabled}
                invalid={field.state.meta.errors.length > 0}
                {...inputProps}
              />
            ) : (
              <Input
                ref={ref}
                id={name}
                type={type === "number" ? "text" : type}
                inputMode={type === "number" ? "decimal" : undefined}
                value={field.state.value ?? ""}
                onChange={(e) => {
                  const val = type === "number"
                    ? e.target.value.replace(",", ".")
                    : e.target.value;
                  field.handleChange(val);
                }}
                onBlur={(e) => {
                  if (type === "number") {
                    const num = parseFloat(e.target.value.replace(",", "."));
                    field.handleChange(isNaN(num) ? 0 : num);
                  }
                  field.handleBlur();
                }}
                disabled={disabled}
                aria-invalid={field.state.meta.errors.length > 0 || undefined}
                className="mt-1"
                {...inputProps}
              />
            )}
            {field.state.meta.errors.length > 0 && (
              <p className="text-xs text-destructive">{field.state.meta.errors[0]}</p>
            )}
          </div>
        )}
      </form.Field>
    );
  }
);

// ---- CurrencyInput internal component ----

interface CurrencyInputProps extends InputOwnProps {
  id: string;
  value: number;
  onChange: (num: number) => void;
  onBlur: () => void;
  disabled?: boolean;
  invalid?: boolean;
}

const CurrencyInput = React.forwardRef<HTMLInputElement, CurrencyInputProps>(
  function CurrencyInput({ id, value, onChange, onBlur, disabled, invalid, ...rest }, ref) {
    const [display, setDisplay] = React.useState(() =>
      value > 0 ? formatRp(value) : ""
    );
    const focusedRef = React.useRef(false);

    // Sync dari luar (misal reset form) hanya saat tidak fokus
    React.useEffect(() => {
      if (!focusedRef.current) {
        setDisplay(value > 0 ? formatRp(value) : "");
      }
    }, [value]);

    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      const digits = e.target.value.replace(/\D/g, "");
      const num = digits ? parseInt(digits, 10) : 0;
      setDisplay(digits ? formatRp(num) : "");
      onChange(num);
    };

    const handleFocus = () => {
      focusedRef.current = true;
      // Tetap tampilkan format saat fokus
      setDisplay(value > 0 ? formatRp(value) : "");
    };

    const handleBlur = () => {
      focusedRef.current = false;
      setDisplay(value > 0 ? formatRp(value) : "");
      onBlur();
    };

    return (
      <div className="relative mt-1">
        <span className="pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-sm text-muted-foreground select-none">
          Rp
        </span>
        <Input
          ref={ref}
          id={id}
          type="text"
          inputMode="numeric"
          value={display}
          onChange={handleChange}
          onFocus={handleFocus}
          onBlur={handleBlur}
          disabled={disabled}
          aria-invalid={invalid || undefined}
          placeholder="0"
          className="pl-9"
          {...rest}
        />
      </div>
    );
  }
);
