import { $$, ajaxForm, getDebugElement, replaceToolbarState } from "./utils.js";

const djDebug = getDebugElement();

function difference(setA, setB) {
    const _difference = new Set(setA);
    for (const elem of setB) {
        _difference.delete(elem);
    }
    return _difference;
}

/**
 * Create an array of dataset properties from a NodeList.
 */
function pluckData(nodes, key) {
    return [...nodes].map((obj) => obj.dataset[key]);
}

function refreshHistory() {
    const formTarget = djDebug.querySelector(".refreshHistory");
    const container = djDebug.querySelector("#djdtHistoryRequests");
    const oldIds = new Set(
        pluckData(
            container.querySelectorAll("tr[data-request-id]"),
            "requestId"
        )
    );

    ajaxForm(formTarget)
        .then((data) => {
            // Remove existing rows first then re-populate with new data
            for (const node of container.querySelectorAll(
                "tr[data-request-id]"
            )) {
                node.remove();
            }
            for (const request of data.requests) {
                container.innerHTML = request.content + container.innerHTML;
            }
        })
        .then(() => {
            const allIds = new Set(
                pluckData(
                    container.querySelectorAll("tr[data-request-id]"),
                    "requestId"
                )
            );
            const newIds = difference(allIds, oldIds);
            const lastRequestId = newIds.values().next().value;
            return {
                allIds,
                newIds,
                lastRequestId,
            };
        })
        .then((refreshInfo) => {
            const newCount = refreshInfo.newIds.size;
            const status = djDebug.querySelector("#djdtStatus");
            if (status) {
                status.textContent = newCount
                    ? `${newCount} new request${
                          newCount === 1 ? "" : "s"
                      } added to history`
                    : "History up to date";
            }
            for (const newId of refreshInfo.newIds) {
                const row = container.querySelector(
                    `tr[data-request-id="${newId}"]`
                );
                row.classList.add("flash-new");
            }
            setTimeout(() => {
                for (const row of container.querySelectorAll(
                    "tr[data-request-id]"
                )) {
                    row.classList.remove("flash-new");
                }
            }, 2000);
        });
}

function switchHistory(newRequestId) {
    const formTarget = djDebug.querySelector(
        `.switchHistory[data-request-id='${newRequestId}']`
    );
    const tbody = formTarget.closest("tbody");

    const highlighted = tbody.querySelector(".djdt-highlighted");
    if (highlighted) {
        highlighted.classList.remove("djdt-highlighted");
    }
    formTarget.closest("tr").classList.add("djdt-highlighted");

    ajaxForm(formTarget).then((data) => {
        if (Object.keys(data).length === 0) {
            const container = djDebug.querySelector("#djdtHistoryRequests");
            container.querySelector(
                `button[data-request-id="${newRequestId}"]`
            ).innerHTML = "Switch [EXPIRED]";
        }
        replaceToolbarState(newRequestId, data);
    });
}

$$.on(djDebug, "click", ".switchHistory", function (event) {
    event.preventDefault();
    switchHistory(this.dataset.requestId);
});

$$.on(djDebug, "click", ".refreshHistory", (event) => {
    event.preventDefault();
    refreshHistory();
});
// We don't refresh the whole toolbar each fetch or ajax request,
// so we need to refresh the history when we open the panel
$$.onPanelRender(djDebug, "HistoryPanel", refreshHistory);
