import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { PGliteWorker } from "@electric-sql/pglite/worker";
import { processorFactory } from "@powerhousedao/common";
import { connectConfig } from "@powerhousedao/connect/config";
import { AnalyticsProvider, useAnalyticsStoreAsync, useProcessors, useRelationalDb, useSetPGliteDB, } from "@powerhousedao/reactor-browser";
import { useProcessorManager } from "@powerhousedao/reactor-browser/connect";
import { childLogger } from "document-drive";
import { generateUUIDBrowser } from "document-model/core";
import { useEffect, useRef } from "react";
const logger = childLogger(["reactor-analytics"]);
function createPgLiteFactoryWorker(databaseName) {
    return async () => {
        const worker = new Worker(new URL("../workers/pglite-worker.js", import.meta.url), {
            type: "module",
        });
        worker.onmessage = (event) => {
            logger.verbose(event.data);
        };
        worker.onerror = (event) => {
            logger.error(event.message);
            throw event.error;
        };
        const pgLiteWorker = new PGliteWorker(worker, {
            meta: {
                databaseName,
            },
        });
        await pgLiteWorker.waitReady;
        return pgLiteWorker;
    };
}
async function registerExternalProcessors(manager, analyticsStore, relationalDb, processorName, processorFactory) {
    return manager.registerFactory(processorName, processorFactory({ analyticsStore, relationalDb }));
}
// async function registerDiffAnalyzer(
//   manager: ProcessorManager,
//   analyticsStore: IAnalyticsStore,
// ) {
//   const { processorFactory } = await import(
//     "@powerhousedao/diff-analyzer/processors"
//   );
//   const unsafeWrappedFactory = (driveHeader: PHDocumentHeader) => {
//     return processorFactory({ analyticsStore })(
//       driveHeader.id,
//     ) as ProcessorRecord[];
//   };
//   return manager.registerFactory(
//     "@powerhousedao/diff-analyzer",
//     unsafeWrappedFactory,
//   );
// }
async function registerDriveAnalytics(manager, analyticsStore) {
    return manager.registerFactory("@powerhousedao/common/drive-analytics", processorFactory({ analyticsStore }));
}
export function DiffAnalyzerProcessor() {
    const store = useAnalyticsStoreAsync();
    const manager = useProcessorManager();
    const hasRegistered = useRef(false);
    useEffect(() => {
        if (!store.data || !manager || hasRegistered.current) {
            return;
        }
        hasRegistered.current = true;
        // registerDiffAnalyzer(manager, store.data).catch(logger.error);
    }, [store.data, manager]);
    return null;
}
export function DriveAnalyticsProcessor() {
    const store = useAnalyticsStoreAsync();
    const manager = useProcessorManager();
    const hasRegistered = useRef(false);
    useEffect(() => {
        if (!store.data || !manager || hasRegistered.current) {
            return;
        }
        hasRegistered.current = true;
        registerDriveAnalytics(manager, store.data)
            .then(() => {
            logger.verbose("Drive analytics processor registered");
        })
            .catch(logger.error);
    }, [store.data, manager]);
    return null;
}
export function ExternalProcessors() {
    const processors = useProcessors();
    const store = useAnalyticsStoreAsync();
    const relationalDb = useRelationalDb();
    const manager = useProcessorManager();
    const hasRegistered = useRef(false);
    useEffect(() => {
        if (!store.data ||
            !manager ||
            hasRegistered.current ||
            processors?.length === 0 ||
            !relationalDb.db) {
            return;
        }
        hasRegistered.current = true;
        if (!processors) {
            return;
        }
        for (const processor of processors) {
            registerExternalProcessors(manager, store.data, relationalDb.db, generateUUIDBrowser(), processor).catch(logger.error);
        }
    }, [store.data, manager, relationalDb]);
    return null;
}
export function ProcessorManagerProvider({ children }) {
    const pgLiteFactory = connectConfig.analytics.useWorker
        ? createPgLiteFactoryWorker(connectConfig.analytics.databaseName)
        : undefined;
    const setPGliteDB = useSetPGliteDB();
    // Initialize and handle PGlite factory
    useEffect(() => {
        if (!pgLiteFactory) {
            // If no factory, set to not loading with null db
            setPGliteDB({
                db: null,
                isLoading: false,
                error: null,
            });
            return;
        }
        // Resolve the factory
        pgLiteFactory()
            .then((db) => {
            setPGliteDB({
                db: db,
                isLoading: false,
                error: null,
            });
        })
            .catch((err) => {
            const error = err instanceof Error ? err : new Error(String(err));
            setPGliteDB({
                db: null,
                isLoading: false,
                error,
            });
        });
    }, []);
    const content = (_jsxs(_Fragment, { children: [connectConfig.analytics.diffProcessorEnabled && (_jsx(DiffAnalyzerProcessor, {})), connectConfig.analytics.driveAnalyticsEnabled && (_jsx(DriveAnalyticsProcessor, {})), connectConfig.analytics.externalProcessorsEnabled && (_jsx(ExternalProcessors, {})), children] }));
    return (_jsx(AnalyticsProvider, { options: {
            databaseName: connectConfig.analytics.databaseName,
            pgLiteFactory,
        }, children: content }));
}
//# sourceMappingURL=processor-manager.js.map