import { useState, useCallback, useEffect, useMemo } from 'react';
import moment from 'moment';
import { isNil } from 'ramda';
import { utils, debounce } from '@reltio/mdm-sdk';
import { getEditorMaxDate, getEditorMinDate, getErrorMessage, isDateRangeError } from './helpers';
import { DEFAULT_MAX_DATE, DEFAULT_MIN_DATE } from './constants';
var _a = utils.dates, isValidMomentDateOrNull = _a.isValidMomentDateOrNull, isDateInRange = _a.isDateInRange, momentToDate = _a.momentToDate;
export var useDateEditor = function (_a) {
    var minDateProp = _a.minDate, maxDateProp = _a.maxDate, value = _a.value, onChange = _a.onChange;
    var _b = useState(null), error = _b[0], setError = _b[1];
    var _c = useState(null), editorValue = _c[0], setEditorValue = _c[1];
    var minDate = useMemo(function () { return utils.dates.clearDateTime(isNil(minDateProp) ? DEFAULT_MIN_DATE : minDateProp); }, [minDateProp]);
    var maxDate = useMemo(function () { return utils.dates.clearDateTime(isNil(maxDateProp) ? DEFAULT_MAX_DATE : maxDateProp); }, [maxDateProp]);
    var momentValue = useMemo(function () { return (isNil(value) ? null : moment(value)); }, [value]);
    var editorMinDate = useMemo(function () { return getEditorMinDate(minDate); }, [minDate]);
    var editorMaxDate = useMemo(function () { return getEditorMaxDate(maxDate); }, [maxDate]);
    var errorMessage = useMemo(function () { return getErrorMessage(error); }, [error]);
    var handleError = useCallback(function (error) {
        if (!isDateRangeError(error))
            setError(error);
    }, []);
    var handleChange = useCallback(function (value) {
        setEditorValue(value);
        if (isValidMomentDateOrNull(value) && isDateInRange(minDate, maxDate)(value)) {
            onChange(momentToDate(value));
        }
    }, [minDate, maxDate, onChange]);
    var debouncedHandleChange = useCallback(debounce(handleChange, 0), [handleChange]);
    useEffect(function () {
        setEditorValue(function (prevEditorValue) {
            var datesAreTheSame = moment(prevEditorValue).isSame(momentValue);
            var datesAreInvalid = !isValidMomentDateOrNull(momentValue) && !isValidMomentDateOrNull(prevEditorValue);
            return datesAreTheSame || datesAreInvalid ? prevEditorValue : momentValue;
        });
    }, [momentValue]);
    useEffect(function () {
        if (editorValue === null || editorValue === void 0 ? void 0 : editorValue.isAfter(maxDate)) {
            setError('maxDate');
        }
        else if (editorValue === null || editorValue === void 0 ? void 0 : editorValue.isBefore(minDate)) {
            setError('minDate');
        }
        else {
            setError(function (prevError) { return (isDateRangeError(prevError) ? null : prevError); });
        }
    }, [editorValue, maxDate, minDate]);
    return {
        errorMessage: errorMessage,
        editorValue: editorValue,
        editorMinDate: editorMinDate,
        editorMaxDate: editorMaxDate,
        onChange: debouncedHandleChange,
        onError: handleError
    };
};
