import React, { useEffect, useState } from "react";
import { cn } from "@/lib/utils";
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/ui/input-group";

/**
 * Standalone currency input with a "$" prefix and thousands-separator formatting.
 * Strips the slider and option buttons from the app's BaseMoneyInput — use this
 * for expense row inputs or any context where just the dollar field is needed.
 *
 * Consumers should wrap in <Field> + <FieldLabel> / <FieldError> for label/error display.
 */

export type CurrencyInputProps = {
  /** Current dollar value (whole dollars) */
  value: number;
  /** Called on blur with the parsed integer value */
  onChange: (value: number) => void;
  /** HTML id forwarded to the inner <input> — use for Field/label association */
  id?: string;
  disabled?: boolean;
  placeholder?: string;
  /** Minimum allowed value (default: 0) */
  min?: number;
  /** When true, renders the InputGroup in its error visual state */
  error?: boolean;
  className?: string;
};

function formatDisplay(n: number): string {
  return n.toLocaleString("en-AU", { maximumFractionDigits: 0 });
}

function parseRaw(raw: string): number {
  const digits = raw.replace(/[^0-9.]/g, "");
  const n = parseFloat(digits);
  return isNaN(n) ? 0 : Math.round(n);
}

export function CurrencyInput({
  value,
  onChange,
  id,
  disabled = false,
  placeholder = "0",
  min = 0,
  error = false,
  className,
}: CurrencyInputProps) {
  const [displayValue, setDisplayValue] = useState(() =>
    value > 0 ? formatDisplay(value) : "",
  );
  const [focused, setFocused] = useState(false);

  // Keep display in sync when value changes externally (e.g. form reset)
  useEffect(() => {
    if (!focused) {
      setDisplayValue(value > 0 ? formatDisplay(value) : "");
    }
  }, [value, focused]);

  function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    // Allow digits, comma separators, and one decimal point while typing
    const cleaned = e.target.value.replace(/[^0-9,.]/g, "");
    setDisplayValue(cleaned);
  }

  function handleFocus() {
    setFocused(true);
    // Show bare digits while editing — no commas
    setDisplayValue(value > 0 ? String(value) : "");
  }

  function handleBlur() {
    setFocused(false);
    const parsed = Math.max(min, parseRaw(displayValue));
    onChange(parsed);
    setDisplayValue(parsed > 0 ? formatDisplay(parsed) : "");
  }

  return (
    <InputGroup
      className={cn(className)}
      data-disabled={disabled ? "true" : undefined}
    >
      <InputGroupAddon align="inline-start">$</InputGroupAddon>
      <InputGroupInput
        id={id}
        type="text"
        inputMode="numeric"
        value={displayValue}
        onChange={handleChange}
        onFocus={handleFocus}
        onBlur={handleBlur}
        placeholder={placeholder}
        disabled={disabled}
        aria-invalid={error ? "true" : undefined}
      />
    </InputGroup>
  );
}
