import { Minus, Plus } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { formatCurrency } from '@/pages/investments/utils';
import {
    clampInvestmentAmount,
    formatUsdDraft,
    parseUsdInput,
    sanitizeUsdDraft,
} from '@/pages/investments/utils';

type InvestmentAmountFieldProps = {
    amount: number;
    minAmount: number;
    maxAmount: number;
    reinvestMode?: boolean;
    onAmountChange: (amount: number) => void;
};

function resolveStepUsd(minAmount: number, maxAmount: number): number {
    const span = maxAmount - minAmount;

    if (span <= 1) {
        return 0.01;
    }

    if (span <= 25) {
        return 1;
    }

    if (span <= 500) {
        return 10;
    }

    return 50;
}

export function InvestmentAmountField({
    amount,
    minAmount,
    maxAmount,
    reinvestMode = false,
    onAmountChange,
}: InvestmentAmountFieldProps) {
    const stepUsd = resolveStepUsd(minAmount, maxAmount);
    const [draft, setDraft] = useState(() => formatUsdDraft(amount));
    const isFocusedRef = useRef(false);
    const inputRef = useRef<HTMLInputElement>(null);

    useEffect(() => {
        if (!isFocusedRef.current) {
            setDraft(formatUsdDraft(amount));
        }
    }, [amount]);

    function commitDraft(raw: string): void {
        const parsed = parseUsdInput(raw);

        if (parsed === null) {
            const fallback = clampInvestmentAmount(minAmount, minAmount, maxAmount);
            setDraft(formatUsdDraft(fallback));
            onAmountChange(fallback);

            return;
        }

        const clamped = clampInvestmentAmount(parsed, minAmount, maxAmount);
        setDraft(formatUsdDraft(clamped));
        onAmountChange(clamped);
    }

    function nudge(delta: number): void {
        const base = parseUsdInput(draft) ?? amount;
        const next = clampInvestmentAmount(base + delta, minAmount, maxAmount);
        setDraft(formatUsdDraft(next));
        onAmountChange(next);
        inputRef.current?.focus();
    }

    return (
        <div className="space-y-4 rounded-lg border border-primary/30 bg-primary/10 p-4">
            <div className="space-y-1">
                <Label className="text-xs text-muted-foreground" htmlFor="investment_amount_manual">
                    Monto a invertir
                </Label>
                <p className="text-xs text-muted-foreground leading-snug">
                    Entre {formatCurrency(minAmount)} y {formatCurrency(maxAmount)}.
                    {reinvestMode ? (
                        <>
                            {' '}
                            En <strong className="text-foreground">reinversión</strong> el mínimo es tu saldo
                            disponible (desde 0,01 US$).
                        </>
                    ) : null}
                </p>
            </div>

            <div className="flex items-stretch gap-2">
                <Button
                    aria-label="Disminuir monto"
                    className="h-12 w-12 shrink-0"
                    disabled={amount <= minAmount}
                    size="icon"
                    type="button"
                    variant="outline"
                    onClick={() => nudge(-stepUsd)}
                >
                    <Minus className="size-4" />
                </Button>

                <div className="border-primary/25 bg-background focus-within:border-ring focus-within:ring-ring/50 flex min-w-0 flex-1 items-center gap-2 rounded-md border px-3 shadow-xs focus-within:ring-[3px]">
                    <span
                        aria-hidden
                        className="text-muted-foreground shrink-0 text-sm font-medium tabular-nums"
                    >
                        US$
                    </span>
                    <input
                        ref={inputRef}
                        autoComplete="off"
                        autoCorrect="off"
                        className="placeholder:text-muted-foreground min-w-0 flex-1 bg-transparent py-2 text-2xl font-bold tracking-tight text-foreground tabular-nums outline-none sm:text-3xl"
                        enterKeyHint="done"
                        id="investment_amount_manual"
                        inputMode="decimal"
                        name="investment_amount"
                        spellCheck={false}
                        type="text"
                        value={draft}
                        onBlur={() => {
                            isFocusedRef.current = false;
                            commitDraft(draft);
                        }}
                        onChange={(event) => {
                            const sanitized = sanitizeUsdDraft(event.target.value);
                            setDraft(sanitized);

                            const parsed = parseUsdInput(sanitized);
                            if (parsed !== null) {
                                onAmountChange(
                                    clampInvestmentAmount(parsed, minAmount, maxAmount),
                                );
                            }
                        }}
                        onFocus={() => {
                            isFocusedRef.current = true;
                        }}
                    />
                </div>

                <Button
                    aria-label="Aumentar monto"
                    className="h-12 w-12 shrink-0"
                    disabled={amount >= maxAmount}
                    size="icon"
                    type="button"
                    variant="outline"
                    onClick={() => nudge(stepUsd)}
                >
                    <Plus className="size-4" />
                </Button>
            </div>

            <p className="text-center text-xs text-muted-foreground">
                Usa el teclado numérico, los botones ±{stepUsd} o la barra deslizante.
            </p>
        </div>
    );
}
