import { jsx as _jsx } from "react/jsx-runtime";
import React from "react";
import ReactDOM from "react-dom/client";
import { QueryClient, QueryClientProvider } from "react-query";
import * as RestApi from "../components/client";
import { OpenK9Client, OpenK9ClientContext, } from "../components/client";
import * as RendererComponents from "../renderer-components";
import { Main } from "./Main";
import { RangeProvider } from "../components/useRange";
export const rendererComponents = RendererComponents;
export class OpenK9 {
    static dependencies = {
        React,
        ReactDOM,
        RestApi,
        SearchFrontend: {
            OpenK9,
            rendererComponents,
        },
    };
    configuration;
    /**
     * rest client instance used by this ui
     * @see {@link OpenK9Client} from **@openk9/rest-api** package
     */
    client;
    root;
    queryClient;
    constructor(configuration = {}) {
        this.configuration = { ...defaultConfiguration, ...configuration };
        this.root = ReactDOM.createRoot(this.getRootElement());
        this.queryClient = new QueryClient({
            defaultOptions: {
                queries: {
                    refetchOnWindowFocus: false,
                    notifyOnChangeProps: ["data", "error"], // for better performance
                },
            },
        });
        this.client = OpenK9Client({
            onAuthenticated: () => {
                this.queryClient.invalidateQueries();
            },
            tenant: this.configuration.tenant ?? "",
            useKeycloak: this.configuration.useKeycloak,
            waitKeycloackForToken: this.configuration.waitKeycloackForToken,
            callback: this.configuration.callbackClient,
        });
        this.render();
    }
    /** returns current configuration */
    getConfiguration() {
        return { ...this.configuration };
    }
    /**
     * updates configuration with provided fields
     *
     * also accepts a function that produces an object with fields to update
     */
    updateConfiguration = (configuration) => {
        if (typeof configuration === "function") {
            this.configuration = {
                ...this.configuration,
                ...configuration(this.configuration),
            };
        }
        else {
            this.configuration = { ...this.configuration, ...configuration };
        }
        this.notify("configurationChange", this.configuration);
        this.render();
    };
    render() {
        if (this.configuration.enabled) {
            this.root.render(_jsx(React.StrictMode, { children: _jsx(React.Suspense, { children: _jsx(OpenK9ClientContext.Provider, { value: this.client, children: _jsx(QueryClientProvider, { client: this.queryClient, children: _jsx(RangeProvider, { children: _jsx(Main, { configuration: this.configuration, onConfigurationChange: this.updateConfiguration, onQueryStateChange: this.onQueryStateChange }) }) }) }) }) }));
        }
        else {
            this.root.unmount();
        }
    }
    getRootElement() {
        const isDevelopment = process.env.NODE_ENV === "development";
        if (!isDevelopment) {
            return document.createDocumentFragment();
        }
        else {
            // needed for hot-reloading in development
            const win = window;
            if (win["openk9-react-root"]) {
                return win["openk9-react-root"];
            }
            else {
                win["openk9-react-root"] = document.createDocumentFragment();
                return win["openk9-react-root"];
            }
        }
    }
    /** authenticate the user with given token */
    authenticate = ({ token }) => {
        return this.client.authenticate({ token: token || "" });
    };
    /** logs out the user, all subsequent queries will be anonymous */
    deauthenticate = () => {
        return this.client.deauthenticate();
    };
    listeners = {
        configurationChange: new Set(),
        queryStateChange: new Set(),
    };
    notify(event, payload) {
        this.listeners[event].forEach((listener) => listener(payload));
    }
    addEventListener(event, listener) {
        this.listeners[event].add(listener);
    }
    removeEventListener(event, listener) {
        this.listeners[event].delete(listener);
    }
    onQueryStateChange = (queryState) => {
        this.notify("queryStateChange", queryState);
    };
}
const defaultConfiguration = {
    autocompleteEnabled: false,
    activeFilters: null,
    activeFiltersConfigurable: null,
    allFilters: null,
    callbackClient: () => null,
    calendar: null,
    calendarMobile: null,
    calendarVertical: null,
    changeLanguage: null,
    correction: null,
    dataRangePicker: null,
    dataRangePickerVertical: null,
    defaultString: null,
    extraClass: null,
    languageSelect: null,
    debounceTimeSearch: null,
    defaultTokens: [],
    externalSearchTokens: null,
    detailMobile: null,
    details: null,
    enabled: false,
    filters: null,
    filtersConfigurable: null,
    filtersHorizontal: null,
    filtersMobile: null,
    filtersMobileLiveChange: null,
    filtersMobileLiveChangeBasic: null,
    mobileFiltersBasicLiveChange: null,
    filtersMobileBasic: null,
    filtersMobileBasicCallback: () => null,
    filterTokens: [],
    generateResponse: null,
    icons: null,
    isActiveSkeleton: { results: null, filters: null, tabs: null },
    isQueryAnalysis: true,
    login: null,
    memoryResults: null,
    numberResult: null,
    numberResultOfFilters: null,
    queryStringValues: null,
    queryStringMap: null,
    removeFilters: null,
    removeFiltersConfigurable: null,
    resultList: null,
    resultListPagination: null,
    results: null,
    resultsDisplayMode: { type: "infinite" },
    search: null,
    searchWithButton: null,
    select: null,
    searchAutoselect: true,
    searchConfigurable: null,
    searchMobile: null,
    searchReplaceText: true,
    searchWithSuggestions: null,
    showSyntax: true,
    skeleton: null,
    sort: [],
    sortResults: null,
    sortable: null,
    sortableConfigurable: null,
    sortResultConfigurable: null,
    sortResultListCustom: null,
    skeletonFiltersCustom: null,
    skeletonResultsCustom: null,
    skeletonSuggestionCustom: null,
    skeletonTabsCustom: null,
    styledSkeletonResults: null,
    tabs: null,
    tabsConfigurable: null,
    template: null,
    tenant: null,
    token: null,
    totalResult: null,
    totalResultConfigurable: null,
    totalResultMobile: null,
    useGenerativeApi: null,
    useQueryAnalysis: true,
    useKeycloak: true,
    useQueryString: true,
    useQueryStringFilters: true,
    useFilterConfiguration: true,
    viewButton: false,
    waitKeycloackForToken: false,
    changeSortResult: (sort) => sort,
    overrideTabs: (tabs) => tabs,
};
window.OpenK9 = OpenK9;
