import { getGlobalQueue } from "./global.js";
import { REMAINING_EVENT } from "../types/events/remaining.js";
import { localStorageTest } from "../utils/localStorageTest.js";
import { getStaticOptions } from "../utils/options.js";
import { request } from "../utils/request.js";
import { locationRestJobsGet } from "../wp-api/jobs.get.js";

import type { RemainingEvent } from "../types/events/remaining.js";
import type { ParamsRouteJobsGet, RequestRouteJobsGet, ResponseRouteJobsGet } from "../wp-api/jobs.get.js";

/**
 * Allows to restore jobs from the local storage. This is helpful especially
 * when the jobs got locked by the server and could not be "restored the next time".
 */
const LOCAL_STORAGE_KEY_RESTORE_JOBS = "real-queue-restore-jobs";

/**
 * Fetch the next list of jobs so we can populate to our queue.
 */
async function restoreJobsFromLocalStorage(queueClass = getGlobalQueue()) {
    if (localStorageTest()) {
        const lsKey = `${LOCAL_STORAGE_KEY_RESTORE_JOBS}-${getStaticOptions().localStorageSuffix}`;
        const ids = localStorage.getItem(lsKey)?.split(",").map(Number).filter(Boolean).join(",");
        localStorage.removeItem(lsKey);
        if (ids) {
            try {
                const { jobs, remaining } = await request<
                    RequestRouteJobsGet,
                    ParamsRouteJobsGet,
                    ResponseRouteJobsGet
                >({
                    location: locationRestJobsGet,
                    params: {
                        ids,
                    },
                });

                const unfinished = jobs.filter(
                    ({ process, process_total, runs, retries, locked }) =>
                        process < process_total && runs < retries + 1 && !locked,
                );

                queueClass.enqueueFromList(unfinished);
                getStaticOptions().remaining = remaining;

                document.dispatchEvent(
                    new CustomEvent<RemainingEvent>(REMAINING_EVENT, {
                        detail: {
                            remaining,
                        },
                    }),
                );

                // Save back the "unfinished" jobs so dangling jobs are automatically removed
                localStorage.setItem(lsKey, unfinished.map(({ id }) => id).join(","));

                return unfinished.length > 0;
            } catch (e) {
                // Silence is golden.
            }
        }
    }

    return false;
}

export { LOCAL_STORAGE_KEY_RESTORE_JOBS, restoreJobsFromLocalStorage };
