/**
 * The entry point for the admin side wp-admin resource.
 */
import "@devowl-wp/utils/antd.scss";
import { createRoot } from "react-dom/client";

import { ready, waitObject } from "@devowl-wp/react-utils";

import { ErrorModal } from "./components/errorModal/modal.js";
import { Provider } from "./components/provider.js";
import { createActivityDetector } from "./queue/activityDetector.js";
import { fetchStatus } from "./queue/fetchStatus.js";
import { refreshQueue } from "./queue/refreshQueue.js";
import { restoreJobsFromLocalStorage } from "./queue/restoreFromLocalStorage.js";
import { checkWorkerNotifications } from "./queue/tabBridge/checkNotifications.js";
import { clearWorkerNotifications } from "./queue/tabBridge/clearNotifications.js";
import { lockTab } from "./queue/tabBridge/lockTab.js";
import { CLIENT_JOB_EVENT_PREFIX } from "./types/events/clientJob.js";

import type { ClientJobEvent } from "./types/events/clientJob.js";

declare global {
    interface Window {
        /**
         * Does this tab currently hold the only worker for our queue?
         */
        realQueueWorker?: boolean;
    }
}

ready(async () => {
    // Only allow queue runtime for one tab
    await waitObject(() => (lockTab() ? undefined : "unlocked"), 3000);
    window.addEventListener("beforeunload", () => lockTab(false));
    lockTab(true);

    // Create error modal
    const errorModalElement = document.createElement("div");
    document.body.appendChild(errorModalElement);
    createRoot(errorModalElement).render(
        <Provider>
            <ErrorModal />
        </Provider>,
    );

    // Mark this tab as worker
    clearWorkerNotifications();
    window.realQueueWorker = true;

    setInterval(
        () =>
            checkWorkerNotifications({
                refreshQueue,
            }),
        3000,
    );

    const addedFromLocalStorage = await restoreJobsFromLocalStorage();
    if (!addedFromLocalStorage) {
        // No new items from LocalStorage, check if queue has new items
        refreshQueue(false);
    }
}, "interactive");

ready(() => {
    createActivityDetector();
    fetchStatus(60000);

    // When the tab gets visible, immediate fetch status
    document.addEventListener("visibilitychange", () => {
        if (document.visibilityState === "visible") {
            fetchStatus(true);
        }
    });
});

// Example implementation of a client job
document.addEventListener(`${CLIENT_JOB_EVENT_PREFIX}example`, (async ({
    detail: { job, resolve, fetchJob, saveJobResult },
}: CustomEvent<ClientJobEvent>) => {
    console.log("Lock this job and sleep...", job);

    const { id, process_total } = job;
    await fetchJob(id, true);
    await new Promise<void>((resolve) => setTimeout(resolve, 5000));

    saveJobResult(id, process_total);
    resolve();
}) as any);

export * from "./hooks/index.js";
export * from "./types/index.js";
export * from "./utils/index.js";
export * from "./queue/index.js";
export * from "./wp-api/index.js";
