import { __assign } from "tslib";
import { useMemo, useReducer } from 'react';
import { ValidateOption, useForm as superUseForm, } from './formulr';
import { Subject } from 'rxjs';
import { useAsyncSafeDispatch } from '../utils/hooks/useAsyncSafeDispatch';
import { useObservableEagerState, useObservableState } from 'observable-hooks';
var initialState = {
    submitting: false,
    submitFailed: false,
    submitSucceeded: false,
};
function formReducer(state, action) {
    switch (action.type) {
        case 'SUBMIT_START':
            return __assign(__assign({}, state), { submitting: true });
        case 'SUBMIT_SUCCESS':
            return __assign(__assign({}, state), { submitting: false, submitFailed: false, submitSucceeded: true });
        case 'SUBMIT_ERROR':
            return __assign(__assign({}, state), { submitting: false, submitFailed: true, submitSucceeded: false });
        default:
            return state;
    }
}
var ZentForm = (function () {
    function ZentForm(inner, state, dispatch) {
        var _this = this;
        this.inner = inner;
        this.state = state;
        this.dispatch = dispatch;
        this.submit$ = new Subject();
        this.reset$ = new Subject();
        this.submit = function (e) {
            _this.submit$.next(e);
        };
    }
    Object.defineProperty(ZentForm.prototype, "isSubmitting", {
        get: function () {
            return this.state.submitting;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ZentForm.prototype, "isSubmitFailed", {
        get: function () {
            return this.state.submitFailed;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ZentForm.prototype, "isSubmitSucceeded", {
        get: function () {
            return this.state.submitSucceeded;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ZentForm.prototype, "ctx", {
        get: function () {
            return this.inner.ctx;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ZentForm.prototype, "model", {
        get: function () {
            return this.inner.model;
        },
        enumerable: false,
        configurable: true
    });
    ZentForm.prototype.validate = function (option) {
        if (option === void 0) { option = ValidateOption.Default; }
        return this.inner.model.validate(option);
    };
    ZentForm.prototype.isValid = function () {
        return this.inner.model.valid();
    };
    ZentForm.prototype.isValidating = function () {
        return this.inner.model.isValidating$.getValue();
    };
    ZentForm.prototype.getValue = function () {
        return this.inner.model.getRawValue();
    };
    ZentForm.prototype.getSubmitValue = function () {
        return this.inner.model.getSubmitValue();
    };
    ZentForm.prototype.initialize = function (value) {
        this.inner.model.initialize(value);
    };
    ZentForm.prototype.patchValue = function (value) {
        this.inner.model.patchValue(value);
    };
    ZentForm.prototype.resetValue = function () {
        this.inner.model.reset();
    };
    ZentForm.prototype.reset = function (e) {
        this.reset$.next(e);
    };
    ZentForm.prototype.clear = function () {
        this.inner.model.clear();
    };
    ZentForm.prototype.submitStart = function () {
        this.dispatch({
            type: 'SUBMIT_START',
        });
    };
    ZentForm.prototype.submitSuccess = function () {
        this.dispatch({
            type: 'SUBMIT_SUCCESS',
        });
    };
    ZentForm.prototype.submitError = function () {
        this.dispatch({
            type: 'SUBMIT_ERROR',
        });
    };
    return ZentForm;
}());
export { ZentForm };
export function useForm(arg) {
    var inner = superUseForm(arg);
    var _a = useReducer(formReducer, initialState), state = _a[0], _dispatch = _a[1];
    var dispatch = useAsyncSafeDispatch(_dispatch);
    var form = useMemo(function () { return new ZentForm(inner, state, dispatch); }, [inner, dispatch]);
    form.state = state;
    return form;
}
export function useFormValue(form, defaultValue) {
    return useObservableState(form.model.value$, defaultValue);
}
export function useFormValid(form) {
    return useObservableEagerState(form.model.valid$);
}
