"use client";

import { Controller, type Control, type FieldPath, type FieldValues } from "react-hook-form";

import { formFieldClass, formInputClass } from "@/components/form/common/form-layout";
import { Field, FieldError, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";

function formatReadOnlyNumber(value: unknown) {
  const raw = String(value ?? "").replace(/,/g, "").trim();
  if (!raw) return "";
  const numeric = Number(raw);
  if (Number.isNaN(numeric)) return raw;
  // Preserve source precision (trim trailing zeros) instead of always toFixed(2).
  if (raw.includes("e") || raw.includes("E")) {
    return numeric.toString();
  }
  const fixed = numeric.toFixed(9);
  return fixed.replace(/\.?0+$/, "");
}

type NumberFieldProps<T extends FieldValues> = {
  control: Control<T>;
  name: FieldPath<T>;
  label: string;
  placeholder?: string;
  step?: string;
  min?: string;
  className?: string;
  readOnly?: boolean;
};

export function NumberField<T extends FieldValues>({
  control,
  name,
  label,
  placeholder,
  step = "0.01",
  min = "0",
  className,
  readOnly = false,
}: NumberFieldProps<T>) {
  return (
    <Controller
      control={control}
      name={name}
      render={({ field, fieldState }) => (
        <Field className={cn(formFieldClass, className)} data-invalid={!!fieldState.error}>
          <FieldLabel htmlFor={String(name)}>{label}</FieldLabel>
          <Input
            {...field}
            id={String(name)}
            type={readOnly ? "text" : "number"}
            step={step}
            min={min}
            readOnly={readOnly}
            placeholder={placeholder}
            value={
              field.value === undefined || field.value === null
                ? ""
                : readOnly
                  ? formatReadOnlyNumber(field.value)
                  : field.value
            }
            onChange={(event) => {
              if (readOnly) return;
              const next = event.target.valueAsNumber;
              field.onChange(Number.isNaN(next) ? 0 : next);
            }}
            aria-invalid={!!fieldState.error}
            className={cn(formInputClass, readOnly && "bg-muted/40 text-foreground")}
          />
          {fieldState.error ? <FieldError errors={[fieldState.error]} /> : null}
        </Field>
      )}
    />
  );
}
