import React, { useEffect, useState } from "react";

type BaseProps = Omit<
  React.InputHTMLAttributes<HTMLInputElement>,
  "value" | "onChange"
> & {
  className?: string;
};

type StringProps = BaseProps & {
  value: string;
  onValue: (v: string) => void;
  valueCents?: never;
  onChange?: never;
};

type CentsProps = BaseProps & {
  valueCents: number;
  onChange: (cents: number) => void;
  value?: never;
  onValue?: never;
};

type Props = StringProps | CentsProps;

export default function CurrencyInput({
  className,
  placeholder = "0.00",
  ...rest
}: Props) {
  const mergedClass = ["input", className].filter(Boolean).join(" ");
  const formatString = (raw: string) => {
    const cleanedRaw = raw.replace(/,/g, ".").replace(/[^0-9.]/g, "");
    const parts = cleanedRaw.split(".");
    return parts.length === 1
      ? parts[0]
      : `${parts[0]}.${parts.slice(1).join("").slice(0, 2)}`;
  };

  if ("valueCents" in rest) {
    const { valueCents, onChange, ...inputProps } = rest as CentsProps;
    const [display, setDisplay] = useState<string>("");

    // keep display in sync when valueCents prop changes externally
    useEffect(() => {
      const asNumber = (valueCents ?? 0) / 100;
      setDisplay(Number.isFinite(asNumber) ? asNumber.toString() : "");
    }, [valueCents]);

    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      const formatted = formatString(e.target.value);
      setDisplay(formatted);
      const parsed = Number.parseFloat(formatted);
      if (Number.isFinite(parsed)) {
        onChange(Math.round(parsed * 100));
      }
    };

    return (
      <input
        {...inputProps}
        className={mergedClass}
        inputMode="decimal"
        placeholder={placeholder}
        value={display}
        onChange={handleChange}
        pattern="[0-9]*[.,]?[0-9]*"
      />
    );
  }

  const { value, onValue, ...inputProps } = rest as StringProps;
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    onValue(formatString(e.target.value));
  };
  return (
    <input
      {...inputProps}
      className={mergedClass}
      inputMode="decimal"
      placeholder={placeholder}
      value={value}
      onChange={handleChange}
      pattern="[0-9]*[.,]?[0-9]*"
    />
  );
}
