import { CLIENT_JOB_EVENT_PREFIX } from "../../types/events/clientJob.js";
import { localStorageTest } from "../../utils/localStorageTest.js";
import { getStaticOptions } from "../../utils/options.js";
import { jobDelay } from "../job/delay.js";
import { fetchJob } from "../job/fetchJob.js";
import { saveJobResult } from "../job/saveJobResult.js";
import { LOCAL_STORAGE_KEY_RESTORE_JOBS } from "../restoreFromLocalStorage.js";

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

/**
 * Execute a client job.
 */
async function executeClientJob(job: Job, run = 0): Promise<boolean> {
    let result = false;
    const { id, type, retries } = job;

    try {
        await new Promise<void>((resolve, reject) => {
            document.dispatchEvent(
                new CustomEvent<ClientJobEvent>(`${CLIENT_JOB_EVENT_PREFIX}${type}`, {
                    detail: {
                        job,
                        resolve,
                        reject,
                        run,
                        fetchJob,
                        saveJobResult,
                    },
                }),
            );
        });

        result = true;
    } catch (e) {
        if (run < retries) {
            await jobDelay(job);
            result = await executeClientJob(job, run + 1);
        } else {
            await saveJobResult(id, 0, e);
            result = false;
        }
    }

    // Remove from our localStorage, as we do not need to restore it no longer
    if (run === 0 && localStorageTest()) {
        const lsKey = `${LOCAL_STORAGE_KEY_RESTORE_JOBS}-${getStaticOptions().localStorageSuffix}`;
        const restorable = localStorage.getItem(lsKey)?.split(",").map(Number) || [];
        const idx = restorable.indexOf(id);
        if (idx > -1) {
            restorable.splice(idx, 1);
        }
        localStorage.setItem(lsKey, restorable.join(","));
    }

    return result;
}

export { executeClientJob };
