import $ from "jquery";

import { STATUS_ADDITIONAL_DATA_EVENT, STATUS_EVENT } from "@devowl-wp/real-queue";
import type { StatusAdditionalData, StatusEvent } from "@devowl-wp/real-queue";

import { SCAN_QUEUE_JOB } from "../../types/queue.js";
import { __ } from "../../utils/i18n.js";

type StatusEventRcbScan = StatusEvent<{
    "rcb-scan-notice": {
        countAll: number;
        text: string;
    };
}>;

/**
 * Add listener for the scanner status and automatically update the UI.
 */
function listenScannerStatus() {
    const adminBarNoticeElement = document.getElementById("rcb-scan-result-notice");
    const adminBarNoticeCounterElement = document.querySelector(
        "#wp-admin-bar-rcb-scanner-found-services > a > span:nth-child(2)",
    );
    let fetchAdditionalData = false;

    // Always refresh notice in admin bar with results
    document.addEventListener(STATUS_ADDITIONAL_DATA_EVENT, (async ({
        detail: {
            settings: { additionalData },
        },
    }: CustomEvent<StatusAdditionalData>) => {
        if (adminBarNoticeElement && fetchAdditionalData) {
            additionalData.push("rcb-scan-notice");
        }
    }) as any);

    document.addEventListener(STATUS_EVENT, (({
        detail: {
            currentJobs: { [SCAN_QUEUE_JOB]: currentJob },
            remaining: { [SCAN_QUEUE_JOB]: remainingArr },
            additionalData: { "rcb-scan-notice": rcbScanNotice },
        },
    }: CustomEvent<StatusEventRcbScan>) => {
        let percent = 100;
        const hasFailureJobs = remainingArr?.["failure"] > 0;

        // Only show the badge for full scans
        if (remainingArr && currentJob?.group_position > 0) {
            const { remaining, total } = remainingArr;
            percent = +(((total - remaining) / total) * 100).toFixed(0);
        }

        const nowVisible = percent > 0 && percent < 100;
        const statusElement = document.getElementById("rcb-scanner-status");
        const checklistExclamationMark = document.getElementById("rcb-checklist-overdue");
        fetchAdditionalData = nowVisible;

        // Update admin bar notice
        if (adminBarNoticeElement && rcbScanNotice) {
            adminBarNoticeElement.innerHTML = rcbScanNotice.text;
            adminBarNoticeCounterElement.innerHTML = adminBarNoticeCounterElement.innerHTML.replace(
                /\d+/,
                rcbScanNotice.countAll.toString(),
            );
        }

        if (statusElement) {
            const previousVisible = statusElement.style.display !== "none";

            statusElement.innerHTML = `${percent} %`;
            statusElement.style.display = nowVisible ? "inline-block" : "none";

            // Hide checklist overdue when scanner is active
            if (checklistExclamationMark) {
                checklistExclamationMark.style.display = !nowVisible ? "inline-block" : "none";
            }

            // Show message that it has finished
            if (previousVisible && !nowVisible && !hasFailureJobs) {
                try {
                    // Show for "Scanner" tab when active, or show on "Cookies" menu item when not in config page
                    const $handle = $(
                        [
                            '#real-cookie-banner-component .nav-tab[href="#/scanner"]:not(.nav-tab-active)',
                            '#real-cookie-banner-pro-component .nav-tab[href="#/scanner"]:not(.nav-tab-active)',
                            "body:not(.toplevel_page_real-cookie-banner-component) #toplevel_page_real-cookie-banner-component",
                            "body:not(.toplevel_page_real-cookie-banner-pro-component) #toplevel_page_real-cookie-banner-pro-component",
                        ].join(","),
                    ) as any;
                    const isNavTab = $handle.hasClass("nav-tab");

                    $handle.pointer({
                        content: `<h3>${__("Real Cookie Banner has scanned your website!")}</h3><p>${__(
                            'You may not have noticed, but we have been scanning your website in the background. View <a href="%s">scanner results</a> to obtain consent for used services from your website visitors!',
                            `${isNavTab ? "" : $handle.find("a").attr("href")}#/scanner`,
                        )}</p>`,
                        position: isNavTab ? { edge: "top" } : { edge: "left", align: "bottom" },
                        pointerClass: `wp-pointer arrow-${isNavTab ? "top" : "bottom"}`,
                        pointerWidth: 420,
                    });

                    const widget = $handle.pointer("widget");
                    widget.css({ marginLeft: -10 });

                    if (isNavTab) {
                        widget.find(".wp-pointer-arrow").css({ marginLeft: -38 });
                    }

                    $handle.pointer("open");

                    if (isNavTab) {
                        $handle.add(widget.find("a")).on("click", () => {
                            $handle.pointer("destroy");
                        });
                    }
                } catch (e) {
                    // jQuery or WP Pointer not available, but this does not matter
                }
            }
        }
    }) as any);
}

export { listenScannerStatus };
