this.SelectDataFetcher = class AutoDataFetcher extends CoreCustomClass {
    constructor() {
        super(...arguments);
        this.bindFunctions(this.startRequests);
        this.JSONRequestObject = new JsonRequest();
        let self = this;
        this.fetchedDataListeners = new Set();
        this.fetchCompleted = false;
        document.addEventListener("DOMContentLoaded", () => {
            self.elements = document.querySelectorAll("select[data-load]");
            self.getBoundFunction("startRequests")();
        });
    };

    addFetchedDataListeners(...listeners) {
        let self = this;
        for(const l of listeners) {
            if(!self.fetchCompleted) {
                if(!self.fetchedDataListeners.has(l)) {
                    self.fetchedDataListeners.add(l);
                };
            } else {
                l(self);
            };
        };
    };

    removeFetchedDataListener(l) {
        let self = this;
        if(self.fetchedDataListeners.has(l)) {
            self.fetchedDataListeners.delete(l);
        };
    };

    notifyFetchedDataListeners() {
        let self = this;
        for(const l of self.fetchedDataListeners) {
            l(self);
        };
    };

    startRequests() {
        let self = this;
        self.requests = [];
        for(let e of self.elements) {
            let model = e.dataset.load;
            let domain = e.dataset.domain ? e.dataset.domain : false;
            /** ci aspettiamo {"resources": [[45, nome], [76, nome], ...]} */
            let data = {
                model: model, 
                domain: domain,
                empty_selection: e.dataset.empty,
            };
            self.requests.push(self.JSONRequestObject.makeRequest("/web/fetch-data", data).then((r) => {
                if(r.ok) {
                    return r.json();
                } else {
                    console.warn(e.dataset.load + " - r.ok false");
                    console.warn(r);
                    return new Promise((resolve, reject) => {
                        try {
                            r.json().then((res) => {
                                resolve({error: res});
                            });
                        } catch (error) {
                            console.warn(e.dataset.load + " - Error on promise r.json()");
                            console.warn(error);
                            r.text().then((res) => {
                                resolve({error: res});
                            });
                        };
                    });
                };
            }).then((respRes) => {
                if(respRes.error) {
                    console.error("Error fetching: " + JSON.stringify(data));
                    console.error(respRes.error);
                } else {
                    let resultError = respRes.result.error;
                    if(resultError) {
                        console.warn(e.dataset.load + " - Error fetching records.");
                        console.warn(resultError);
                    } else {
                        if(respRes.result?.resources) {
                            let resources = respRes.result.resources;
                            let isRequired = e.getAttribute("required");
                            let default_category = e.dataset.default_category
                            let newOpts = isRequired && isRequired !== "" && isRequired !== "false" && isRequired !== "undefined" ?  ["<option></option>"] : [];
                            for(let res of resources) {
                                let id = res[0];
                                let name = res[1];
                                if(id) {
                                    newOpts.push(htmlToElement(`<option value="${id}" ${parseInt(id) === parseInt(default_category) ? 'selected="selected"' : ''} >${name}</option>`));
                                } else {
                                    newOpts.push(htmlToElement(`<option value="0" selected="selected">${name}</option>`));
                                };
                            };
                            e.replaceChildren(...newOpts);
                        };
                    };
                };
            }));
        };
        if(self.requests.length > 0) {
            Promise.allSettled(self.requests).then(() => {
                self.fetchCompleted = true;
                self.notifyFetchedDataListeners();
            });
        };
    };
}

this.SelectDataFetcherInstance = new this.SelectDataFetcher();