import { __awaiter } from "tslib";
import React from "react";
import { RuntimeContext, useClient } from "@qorebase/app-component";
import { openAPISourceFetcher } from "./openAPISourceHooks";
import { qoreSourceFetcher } from "./qoreSourceHooks";
import stableHash from "stable-hash";
import useSWR from "swr";
import { useLocation } from "react-router-dom";
import * as queryString from "../../utils/query-string";
import { useStorageToken } from "../qore";
import { useRefreshDataContext } from "../useRefreshData";
export const useSourceHooks = (source, options) => {
    const customSource = RuntimeContext.useSelectState((state) => state.customSources[source.target]);
    const tables = RuntimeContext.useSelectState((state) => state.schema.tables);
    const views = RuntimeContext.useSelectState((state) => state.schema.views);
    const insights = RuntimeContext.useSelectState((state) => state.schema.insights);
    const queries = RuntimeContext.useSelectState((state) => state.schema.queries || []);
    const table = React.useMemo(() => tables.find((table) => table.name === source.target), [tables, source]);
    const view = React.useMemo(() => views.find((view) => view.name === source.target), [views, source]);
    const insight = React.useMemo(() => insights.find((insight) => insight.name === source.target), [insights, source]);
    const query = React.useMemo(() => queries.find((query) => query.name === source.target), [insights, source]);
    const client = useClient();
    const storageToken = useStorageToken();
    const { flag } = useRefreshDataContext();
    const sourceFetcher = React.useMemo(() => customSource
        ? openAPISourceFetcher(source, customSource)
        : qoreSourceFetcher(source, storageToken, insight ? "insight" : view ? "view" : table ? "table" : "query", insight || view || table || query, client, options), [stableHash([customSource, table, view, source])]);
    const useFetch = (params = {}) => {
        const defaultRow = (source.type === "record" &&
            source.defaultRow.type === "row-id" &&
            source.defaultRow.rowId) ||
            null;
        const fetchFirstRow = source.type === "record" && source.defaultRow.type === "first-row";
        const isPaused = !source.target || (!fetchFirstRow && !("rowId" in source || defaultRow));
        const { data, error, isValidating, mutate } = useSWR(["fetch", source, params, flag], () => sourceFetcher.fetch(params), {
            isPaused: () => isPaused,
            refreshInterval: options === null || options === void 0 ? void 0 : options.pollInterval,
            suspense: !isPaused && "prefetch" in source && source.prefetch,
        });
        React.useEffect(() => {
            if (!(options === null || options === void 0 ? void 0 : options.pollInterval))
                return;
            (() => __awaiter(void 0, void 0, void 0, function* () {
                yield mutate();
            }))();
        }, []);
        return {
            data: data,
            error,
            status: error ? "error" : isValidating ? "loading" : "success",
            revalidate: mutate,
        };
    };
    const useFetchList = (params = {}, config) => {
        const isPaused = React.useMemo(() => (config === null || config === void 0 ? void 0 : config.isPaused)
            ? config.isPaused[0] === "and"
                ? !source.target && config.isPaused[1]
                : !source.target || config.isPaused[1]
            : !source.target, [source.target, config === null || config === void 0 ? void 0 : config.isPaused]);
        const basedSuspenseCondition = React.useMemo(() => !isPaused && "prefetch" in source && source.prefetch, [isPaused, source]);
        const suspense = React.useMemo(() => {
            return !!config && !!(config === null || config === void 0 ? void 0 : config.suspense)
                ? config.suspense[0] === "and"
                    ? basedSuspenseCondition && config.suspense[1]
                    : basedSuspenseCondition || config.suspense[1]
                : basedSuspenseCondition;
        }, [basedSuspenseCondition, config === null || config === void 0 ? void 0 : config.suspense]);
        const { data = [], error, isValidating, mutate, } = useSWR(["fetchList", source, params, flag], () => sourceFetcher.fetchList(params), {
            isPaused: () => isPaused,
            refreshInterval: options === null || options === void 0 ? void 0 : options.pollInterval,
            suspense: suspense,
        });
        const location = useLocation();
        const [state, setState] = React.useState({
            currentSession: "closed",
            lastSession: "closed",
        });
        const isModalOpen = React.useMemo(() => {
            const { modalPage, modalH } = queryString.parse(location.search);
            return !!modalPage && !!modalH;
        }, [location.search]);
        const isDifferentSession = React.useMemo(() => state.currentSession !== state.lastSession, [state.currentSession, state.lastSession]);
        const initializeCurrentSession = React.useCallback(() => {
            if (isDifferentSession) {
                setState({ currentSession: "opened", lastSession: "opened" });
            }
            else if (state.currentSession === "closed") {
                setState((state) => (Object.assign(Object.assign({}, state), { currentSession: "opened" })));
            }
        }, [isDifferentSession, state.currentSession]);
        const finishedCurrentSession = React.useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
            if (isDifferentSession) {
                yield mutate();
                setState({ currentSession: "closed", lastSession: "closed" });
            }
            else if (state.currentSession === "opened") {
                setState((state) => (Object.assign(Object.assign({}, state), { currentSession: "closed" })));
            }
        }), [isDifferentSession, state.currentSession, mutate]);
        React.useEffect(() => {
            if (isModalOpen) {
                initializeCurrentSession();
            }
            else if (!isModalOpen) {
                finishedCurrentSession();
            }
        }, [isModalOpen]);
        React.useEffect(() => {
            if (isDifferentSession || !(options === null || options === void 0 ? void 0 : options.pollInterval))
                return;
            (() => __awaiter(void 0, void 0, void 0, function* () {
                yield mutate();
            }))();
        }, []);
        return {
            data,
            error,
            status: error
                ? "error"
                : isValidating && data.length === 0
                    ? "loading"
                    : "success",
            revalidate: mutate,
        };
    };
    const store = (params) => 
    // @ts-ignore
    sourceFetcher.store(params);
    const del = (params) => sourceFetcher.del(params);
    return {
        type: sourceFetcher.type,
        params: sourceFetcher.params,
        inputParams: sourceFetcher.inputParams,
        fields: sourceFetcher.fields,
        useFetch,
        useFetchList,
        store,
        del,
    };
};
//# sourceMappingURL=useSourceHooks.js.map