// QuantityNumberInput.tsx — valor primitivo (number | "" | string numérica)
// Comentarios en español. TS estricto.

import { useQuantity } 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';


export type InputEmptyMode = "blank" | "placeholder" | "value";
export type InputReadOnlyMode = "textlike-input" | "normal";
export type InputSuffixMap = { one: string; other: string; zero?: string };

export type QuantityInputProps = {
    value: number | "" | string;                    // "" → no mostrar nada; string puede venir con separadores
    onChange: (next: number | "") => void;
    readOnly?: boolean;
    readOnlyMode?: InputReadOnlyMode;
    id?: string;
    "aria-label"?: string;
    emptyMode?: InputEmptyMode;                           // cómo presentar vacío
    emptyText?: string;                              // texto de vacío para value-mode/placeholder
    scale?: number;                                  // default 2
    locale?: string;                                 // para plural/sufijo y formateo
    className?: string;

    // Sufijo solo en visual, p.ej. {one:"caja", other:"cajas"}
    displaySuffix?: InputSuffixMap | ((n: number) => string);
    nbspBeforeSuffix?: boolean;                      // separador no rompible
};

export function QuantityInput({
    value,
    onChange,
    readOnly = false,
    readOnlyMode = "textlike-input",
    id,
    "aria-label": ariaLabel = "Quantity",
    emptyMode = "blank",
    emptyText = "",
    scale = 2,
    locale,
    className,
    displaySuffix,
    nbspBeforeSuffix = true,
    ...inputProps
}: QuantityInputProps) {
    const { parse, roundToScale } = useQuantity({ defaultScale: scale });
    const [raw, setRaw] = React.useState<string>("");
    const [focused, setFocused] = React.useState(false);

    const plural = React.useMemo(() => new Intl.PluralRules(locale ?? undefined), [locale]);

    const suffixFor = React.useCallback((n: number): string => {
        if (!displaySuffix) return "";
        if (typeof displaySuffix === "function") return displaySuffix(n);
        const cat = plural.select(Math.abs(n));
        if (n === 0 && displaySuffix.zero) return displaySuffix.zero;
        return displaySuffix[cat as "one" | "other"] ?? displaySuffix.other;
    }, [displaySuffix, plural]);

    const formatNumber = React.useCallback((n: number) => {
        return new Intl.NumberFormat(locale ?? undefined, {
            maximumFractionDigits: scale,
            minimumFractionDigits: Number.isInteger(n) ? 0 : 0,
            useGrouping: false,
        }).format(n);
    }, [locale, scale]);

    // Derivar texto visual desde prop `value`
    const visualText = React.useMemo(() => {
        if (value === "" || value === null || value === undefined) {
            return emptyMode === "value" ? emptyText : "";
        }
        const numeric =
            typeof value === "number"
                ? value
                : (parse(String(value)) ?? Number(String(value).replaceAll(",", ""))); // tolera string numérico

        if (!Number.isFinite(numeric)) return emptyMode === "value" ? emptyText : "";
        const n = roundToScale(numeric, scale);
        const numTxt = formatNumber(n);
        const suf = suffixFor(n);
        return suf
            ? `${numTxt}${nbspBeforeSuffix ? "\u00A0" : " "}${suf}`
            : numTxt;
    }, [value, emptyMode, emptyText, parse, roundToScale, scale, formatNumber, suffixFor, nbspBeforeSuffix]);

    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);
            if (emptyMode === "value" && e.currentTarget.value === emptyText) {
                setRaw("");
                return;
            }
            const n =
                parse(e.currentTarget.value) ??
                (value === "" || value == null
                    ? null
                    : typeof value === "number"
                        ? value
                        : parse(String(value)));
            setRaw(n !== null && n !== undefined ? String(n) : "");
        },
        [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);
            const numTxt = formatNumber(rounded);
            const suf = suffixFor(rounded);
            setRaw(suf ? `${numTxt}${nbspBeforeSuffix ? "\u00A0" : " "}${suf}` : numTxt);
        },
        [isShowingEmptyValue, onChange, emptyMode, emptyText, parse, roundToScale, scale, formatNumber, suffixFor, nbspBeforeSuffix]
    );

    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]
    );

    // ── READ-ONLY como input que parece texto ───────────────────────────────
    if (readOnly && readOnlyMode === "textlike-input") {
        const handleBlockFocus = React.useCallback((e: React.SyntheticEvent<HTMLInputElement>) => {
            e.preventDefault();
            (e.target as HTMLInputElement).blur();
        }, []);
        const handleBlockKey = React.useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
            e.preventDefault();
        }, []);

        return (
            <Input
                id={id}
                aria-label={ariaLabel}
                readOnly
                tabIndex={-1}
                onFocus={handleBlockFocus}
                onMouseDown={handleBlockFocus}
                onKeyDown={handleBlockKey}
                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}
            />
        );
    }

    // ── Editable / readOnly normal ──────────────────────────────────────────
    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}
        />
    );
}
