import React, { useState } from 'react';
/**
 * Entrada monetária BRL padrão do produto.
 *
 * Decisão (Sprint 14): usar **react-number-format** (`NumericFormat`) + `Input` (Ant Design)
 * em vez de `InputNumber` com formatter/parser — melhor posição do cursor, colagem e dígitos
 * contínuos no padrão BR (milhar `.`, decimal `,`, prefixo **R$**). **jQuery / maskmoney não**
 * são usados.
 *
 * Valor no `Form` de Ant Design: `number | undefined` (vazio = `undefined`), alinhado a
 * `toMoneyApiNumber` / `toInputMoneyNumber` em `@/lib/utils/money`.
 */
import { Form, Input } from 'antd';
import type { InputProps, InputRef } from 'antd/es/input';
import type { FormItemProps } from 'antd/es/form';
import { NumericFormat } from 'react-number-format';

type InheritedInputProps = Pick<
    InputProps,
    | 'disabled'
    | 'placeholder'
    | 'size'
    | 'className'
    | 'style'
    | 'id'
    | 'autoFocus'
    | 'readOnly'
    | 'tabIndex'
    | 'variant'
    | 'status'
    | 'onFocus'
    | 'onBlur'
>;

export interface FormMoneyInputProps extends InheritedInputProps {
    name: string | (string | number)[];
    label?: string;
    required?: boolean;
    help?: string;
    /** Texto do prefixo (ex.: `R$`). Espaço antes do valor é aplicado automaticamente. */
    prefix?: string;
    min?: number;
    max?: number;
    precision?: number;
    rules?: FormItemProps['rules'];
}

type MoneyFieldProps = InheritedInputProps & {
    value?: number | null;
    onChange?: (v: number | undefined) => void;
    min?: number;
    max?: number;
    precision?: number;
    prefix?: string;
};

export const MoneyInputControl = React.forwardRef<InputRef, MoneyFieldProps>(function MoneyInputControl(
    { value, onChange, onBlur, onFocus, min = 0, max, precision = 2, prefix = 'R$', ...inputProps },
    ref
) {
    const dec = precision;
    const prefixText = prefix ? `${prefix.replace(/\s+$/u, '')} ` : '';
    /** Após blur: exibe centavos fixos (ex. `10` → `10,00`), estilo maskmoney; no foco, edição livre. */
    const [fixedDecimals, setFixedDecimals] = React.useState(false);

    const handleFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {
        setFixedDecimals(false);
        onFocus?.(e);
    };

    const handleBlur: React.FocusEventHandler<HTMLInputElement> = (e) => {
        onBlur?.(e);
        const v = value;
        if (typeof v === 'number' && Number.isFinite(v)) {
            const rounded = Math.round(v * 10 ** dec) / 10 ** dec;
            if (rounded !== v) {
                onChange?.(rounded);
            }
        }
        setFixedDecimals(true);
    };

    return (
        <NumericFormat<InputProps>
            {...inputProps}
            customInput={Input}
            getInputRef={ref}
            thousandSeparator="."
            decimalSeparator=","
            decimalScale={dec}
            fixedDecimalScale={fixedDecimals}
            allowNegative={min < 0}
            prefix={prefixText || undefined}
            inputMode="decimal"
            value={value === null || value === undefined ? '' : value}
            onValueChange={(vals) => {
                onChange?.(vals.floatValue === undefined ? undefined : vals.floatValue);
            }}
            onFocus={handleFocus}
            onBlur={handleBlur}
            isAllowed={(values) => {
                const { floatValue } = values;
                if (floatValue === undefined) return true;
                if (floatValue < min) return false;
                if (max !== undefined && floatValue > max) return false;
                return true;
            }}
        />
    );
});

export default function FormMoneyInput({
    name,
    label,
    required = false,
    help,
    prefix = 'R$',
    min = 0,
    max,
    precision = 2,
    rules,
    ...inputProps
}: FormMoneyInputProps) {
    const formRules = required
        ? [{ required: true, message: `${label || 'Campo'} é obrigatório` }, ...(rules || [])]
        : rules;

    return (
        <Form.Item name={name} label={label} rules={formRules} help={help}>
            <MoneyInputControl min={min} max={max} precision={precision} prefix={prefix} {...inputProps} />
        </Form.Item>
    );
}
