"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useMaskedValue = void 0;
const isDate_1 = require("@astral/utils/date/isDate");
const react_1 = require("react");
const date_1 = require("../../../utils/date");
/**
 * Хук для управления значением для MaskField
 */
const useMaskedValue = ({ currentValue, mask, onChangeValue, }) => {
    const [maskedValue, setMaskedValue] = (0, react_1.useState)(() => currentValue ? (0, date_1.formatDate)(currentValue, mask) : '');
    const maskedValueRef = (0, react_1.useRef)(maskedValue);
    /**
     * Ввод в маску: синхронизируем локальное значение и ref (ref нужен на blur и после выбора даты из календаря,
     * чтобы не читать устаревший state).
     * `onChangeValue` вызываем только при пустой строке (`null`) или когда маска синтаксически полная —
     * иначе partial не уходит наружу до завершения ввода или до blur (см. `handleMaskedValueBlur`).
     */
    const handleMaskedValueChange = (value) => {
        setMaskedValue(value);
        maskedValueRef.current = value;
        if (!value) {
            onChangeValue?.(null, value);
            return;
        }
        if (!(0, date_1.isMaskedDateSyntacticallyComplete)(value, mask)) {
            return;
        }
        onChangeValue?.((0, date_1.parseDate)(value, mask), value);
    };
    /**
     * Blur поля: если осталась непустая неполная маска — один раз отдаём `Invalid Date` в `onChangeValue`,
     * чтобы формы могли показать ошибку. Пустая строка и полная маска не дублируют уже отправленный `onChange`.
     */
    const handleMaskedValueBlur = () => {
        const currentMaskedValue = maskedValueRef.current;
        if (!currentMaskedValue) {
            return;
        }
        if ((0, date_1.isMaskedDateSyntacticallyComplete)(currentMaskedValue, mask)) {
            return;
        }
        onChangeValue?.(new Date(Number.NaN), currentMaskedValue);
    };
    const handleChangeMaskedDate = (date) => {
        const formatted = (0, date_1.formatDate)(date, mask);
        setMaskedValue(formatted);
        maskedValueRef.current = formatted;
        onChangeValue?.(date, formatted);
    };
    // здесь происходит реакция на изменение value из вне (управляемый компонент)
    (0, react_1.useEffect)(() => {
        // если новое значение пустое, то сбрасываем значение MaskField
        if (!currentValue) {
            setMaskedValue('');
            maskedValueRef.current = '';
            return;
        }
        // здесь обрабатывается сценарий, когда в инпут вводится невалидная дата и при этом currentValue становится Invalid Date
        // в таком случае сравнить даты напрямую не получится
        if (!(0, isDate_1.isDate)(currentValue) && maskedValue) {
            return;
        }
        // сравнение только при полной маске, иначе getTime() от parseDate может быть NaN
        const isEqualValueAndMaskedDate = (0, date_1.isMaskedDateSyntacticallyComplete)(maskedValue, mask) &&
            currentValue.getTime() === (0, date_1.parseDate)(maskedValue, mask).getTime();
        // если даты не равны, то значит изменился currentValue из вне и надо синхронизировать maskedValue
        if (!isEqualValueAndMaskedDate) {
            const formatted = (0, date_1.formatDate)(currentValue, mask);
            setMaskedValue(formatted);
            maskedValueRef.current = formatted;
        }
    }, [currentValue]);
    return {
        maskedValue,
        onMaskedValueChange: handleMaskedValueChange,
        onMaskedValueBlur: handleMaskedValueBlur,
        onMaskedDateChange: handleChangeMaskedDate,
    };
};
exports.useMaskedValue = useMaskedValue;
