"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("../utils");
class FocusService {
    constructor(formContext) {
        this.focusHandlers = {};
        this.formContext = formContext;
        this.focus = this.focus.bind(this);
        this.focusNextInput = this.focusNextInput.bind(this);
    }
    setFormContext(formContext) {
        this.formContext = formContext;
    }
    addFocusHandler(id, fn) {
        if (!this.focusHandlers[id])
            this.focusHandlers[id] = [];
        this.focusHandlers[id].push(fn);
    }
    removeFocusHandler(id, fn) {
        if (!this.focusHandlers[id]) {
            console.warn(`laji-form warning: removing focus handler that isn't registered for id ${id}.`);
            return;
        }
        this.focusHandlers[id] = this.focusHandlers[id].filter(_fn => fn !== _fn);
    }
    focus(id) {
        const idParts = id.split("_");
        // Some components focus asynchronously (due to state changes etc), so we reduce
        // the focus handlers to a promise chain.
        let _id = "";
        idParts.reduce((promise, idPart) => {
            return promise.then(() => {
                _id = _id ? `${_id}_${idPart}` : idPart;
                return (this.focusHandlers[_id] || []).reduce((_promise, fn) => {
                    const status = fn(); // Either undefined or a Promise.
                    return status !== undefined ? status : Promise.resolve();
                }, Promise.resolve());
            });
        }, Promise.resolve()).then(() => {
            const panelContainer = document.querySelector(`#${id}-panel`);
            const container = this.formContext.utils.getSchemaElementById(id);
            const errorContainer = document.querySelector(`#laji-form-error-container-${id}`);
            const elem = panelContainer || container || errorContainer;
            const input = document.querySelector(`#${id}`);
            if (elem)
                (0, utils_1.scrollIntoViewIfNeeded)(elem, this.formContext.topOffset, this.formContext.bottomOffset);
            if (input && input.focus) {
                input.focus();
            }
            if (!elem)
                return;
            (0, utils_1.highlightElem)(elem);
        });
    }
    focusNextInput(reverse = false) {
        if (!this.formContext.formRef.current) {
            console.warn("Focus service doesn't have ref to the form");
            return;
        }
        return this.formContext.utils.focusNextInput(reverse);
    }
}
exports.default = FocusService;
