import { formatCurrency } from '@erp/core';
import { useMoney } from '@erp/core/hooks';
import { Input } from '@repo/shadcn-ui/components';
import { cn } from '@repo/shadcn-ui/lib/utils';
import * as React from "react";
import { findFocusableInCell, focusAndSelect } from './input-utils';
import { InputEmptyMode, InputReadOnlyMode } from './quantity-input';


export type AmountInputProps = {
    value: number | string;          // "" → no mostrar nada; string puede venir con separadores
    onChange: (next: number | string) => void;
    readOnly?: boolean;
    readOnlyMode?: InputReadOnlyMode;          // default "textlike-input"
    id?: string;
    "aria-label"?: string;
    step?: number;                        // ↑/↓; default 0.01
    emptyMode?: InputEmptyMode;                // cómo presentar vacío
    emptyText?: string;                   // texto en vacío para value/placeholder
    scale?: number;                       // decimales; default 2 (ej. 4 para unit_amount)
    languageCode?: string;                      // p.ej. "es-ES"
    currencyCode?: string;                    // p.ej. "EUR"
    className?: string;
};

export function AmountInput({
    value,
    onChange,
    readOnly = false,
    readOnlyMode = "textlike-input",
    id,
    "aria-label": ariaLabel = "Amount",
    emptyMode = "blank",
    emptyText = "",
    scale = 2,
    languageCode = 'es',
    currencyCode = "EUR",
    className,
    ...inputProps
}: AmountInputProps) {

    // Hook de dinero para parseo/redondeo consistente con el resto de la app
    const { parse, roundToScale } = useMoney({ locale: languageCode, fallbackCurrency: currencyCode as any });

    const [raw, setRaw] = React.useState<string>("");
    const [focused, setFocused] = React.useState(false);

    const formatCurrencyNumber = React.useCallback(
        (n: number) => formatCurrency(n, scale, currencyCode, languageCode),
        [languageCode, currencyCode, scale]
    );

    // Derivar texto visual desde prop `value`
    const visualText = React.useMemo(() => {
        if (value === "" || value == null) {
            return emptyMode === "value" ? emptyText : "";
        }
        const numeric =
            typeof value === "number"
                ? value
                : (parse(String(value)) ?? Number(String(value).replace(/[^\d.,\-]/g, "").replace(/\./g, "").replace(",", ".")));
        if (!Number.isFinite(numeric)) return emptyMode === "value" ? emptyText : "";
        const n = roundToScale(numeric, scale);
        return formatCurrencyNumber(n);
    }, [value, emptyMode, emptyText, parse, roundToScale, scale, formatCurrencyNumber]);

    const isShowingEmptyValue = emptyMode === "value" && raw === emptyText;

    // Sin foco → mantener visual
    React.useEffect(() => {
        if (!focused) setRaw(visualText);
    }, [visualText, focused]);

    const handleChange = React.useCallback(
        (e: React.ChangeEvent<HTMLInputElement>) => {
            setRaw(e.currentTarget.value);
        },
        []
    );

    const handleFocus = React.useCallback(
        (e: React.FocusEvent<HTMLInputElement>) => {
            setFocused(true);
            // pasar de visual con símbolo → crudo
            if (emptyMode === "value" && e.currentTarget.value === emptyText) {
                setRaw("");
                return;
            }
            const current =
                parse(e.currentTarget.value) ??
                (value === "" || value == null
                    ? null
                    : typeof value === "number"
                        ? value
                        : parse(String(value)));
            setRaw(current !== null && current !== undefined ? String(current) : "");
        },
        [emptyMode, emptyText, parse, value]
    );

    const handleBlur = React.useCallback(
        (e: React.FocusEvent<HTMLInputElement>) => {
            setFocused(false);
            const txt = e.currentTarget.value.trim();
            if (txt === "" || isShowingEmptyValue) {
                onChange("");
                setRaw(emptyMode === "value" ? emptyText : "");
                return;
            }
            const n = parse(txt);
            if (n === null) {
                onChange("");
                setRaw(emptyMode === "value" ? emptyText : "");
                return;
            }
            const rounded = roundToScale(n, scale);
            onChange(rounded);
            setRaw(formatCurrencyNumber(rounded)); // vuelve a visual con símbolo
        },
        [isShowingEmptyValue, onChange, emptyMode, emptyText, parse, roundToScale, scale, formatCurrencyNumber]
    );

    const handleKeyDown = React.useCallback(
        (e: React.KeyboardEvent<HTMLElement>) => {
            if (readOnly) return;

            const keys = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
            if (!keys.includes(e.key)) return;

            e.preventDefault();

            const current = e.currentTarget as HTMLElement;
            const rowIndex = Number(current.dataset.rowIndex);
            const colIndex = Number(current.dataset.colIndex);

            let nextRow = rowIndex;
            let nextCol = colIndex;

            switch (e.key) {
                case "ArrowUp":
                    nextRow--;
                    break;
                case "ArrowDown":
                    nextRow++;
                    break;
                case "ArrowLeft":
                    nextCol--;
                    break;
                case "ArrowRight":
                    nextCol++;
                    break;
            }

            const nextElement = findFocusableInCell(nextRow, nextCol);
            console.log(nextElement);
            if (nextElement) {
                focusAndSelect(nextElement);
            }
        },
        [readOnly]
    );

    const handleBlock = React.useCallback((e: React.SyntheticEvent<HTMLInputElement>) => {
        e.preventDefault();
        (e.target as HTMLInputElement).blur();
    }, []);

    if (readOnly && readOnlyMode === "textlike-input") {
        return (
            <Input
                id={id}
                aria-label={ariaLabel}
                readOnly
                tabIndex={-1}
                onFocus={handleBlock}
                onMouseDown={handleBlock}
                onKeyDown={(e) => e.preventDefault()}
                value={visualText}
                className={cn(
                    "w-full bg-transparent p-0 text-right tabular-nums border-0 shadow-none",
                    "focus:outline-none focus:ring-0 [caret-color:transparent] cursor-default",
                    className
                )}
                {...inputProps}
            />
        );
    }

    return (
        <Input
            id={id}
            aria-label={ariaLabel}
            inputMode="decimal"
            pattern="[0-9]*[.,]?[0-9]*"
            className={cn(
                "w-full bg-transparent p-0 text-right tabular-nums h-8 px-1  shadow-none",
                "border-none",
                "focus:bg-background",
                "focus-visible:border-ring focus-visible:ring-ring/20 focus-visible:ring-[2px]",
                "hover:border hover:ring-ring/20 hover:ring-[2px]",
                className
            )}
            readOnly={readOnly}
            placeholder={emptyMode === "placeholder" && (value === "" || value == null) ? emptyText : undefined}
            value={raw}
            onChange={handleChange}
            onFocus={handleFocus}
            onBlur={handleBlur}
            onKeyDown={handleKeyDown}
            {...inputProps}
        />
    );
}
