// retoor <retoor@molodetz.nl>

import { Http } from "./Http.js";
import { JobPoller } from "./JobPoller.js";

export class PlanningGenerator {
    constructor() {
        this.active = false;
        document.addEventListener("click", (event) => {
            const button = event.target.closest("[data-planning-generate]");
            if (!button) return;
            event.preventDefault();
            this.generate(button);
        });
        document.addEventListener("change", (event) => {
            if (event.target.closest("[data-planning-select-all]")) {
                this.toggleAll(event.target.checked);
                this.syncSelection();
            } else if (event.target.closest("[data-planning-ticket]")) {
                this.syncSelection();
            }
        });
        this.syncSelection();
    }

    tickets() {
        return Array.from(document.querySelectorAll("[data-planning-ticket]"));
    }

    selectedNumbers() {
        return this.tickets()
            .filter((box) => box.checked)
            .map((box) => box.value);
    }

    toggleAll(checked) {
        this.tickets().forEach((box) => {
            box.checked = checked;
        });
    }

    syncSelection() {
        const tickets = this.tickets();
        if (!tickets.length) return;
        const selected = tickets.filter((box) => box.checked).length;
        const count = document.querySelector("[data-planning-count]");
        if (count) {
            count.textContent = `${selected} of ${tickets.length} selected`;
        }
        const master = document.querySelector("[data-planning-select-all]");
        if (master) {
            master.checked = selected === tickets.length;
            master.indeterminate = selected > 0 && selected < tickets.length;
        }
        const button = document.querySelector("[data-planning-generate]");
        if (button) button.disabled = selected === 0;
    }

    elements() {
        return {
            status: document.querySelector("[data-planning-status]"),
            result: document.querySelector("[data-planning-result]"),
            empty: document.querySelector("[data-planning-empty]"),
            report: document.querySelector("[data-planning-report]"),
            download: document.querySelector("[data-planning-download]"),
        };
    }

    async generate(button) {
        if (this.active) return;
        const numbers = this.selectedNumbers();
        if (this.tickets().length && !numbers.length) {
            window.app.toast.show("Select at least one ticket", { type: "error" });
            return;
        }
        this.active = true;
        button.disabled = true;
        button.classList.add("is-loading");
        const ui = this.elements();
        if (ui.empty) ui.empty.hidden = true;
        if (ui.result) ui.result.hidden = true;
        if (ui.status) ui.status.hidden = false;
        try {
            const action = button.dataset.action || "/issues/planning";
            const job = await Http.sendForm(action, { numbers: numbers.join(",") });
            await this.poll(job.status_url, ui);
        } catch (error) {
            window.app.toast.show("Could not start the planning report", { type: "error" });
            if (ui.status) ui.status.hidden = true;
            if (ui.empty) ui.empty.hidden = false;
        } finally {
            this.active = false;
            button.disabled = false;
            button.classList.remove("is-loading");
            this.syncSelection();
        }
    }

    poll(statusUrl, ui) {
        return JobPoller.run(statusUrl, {
            intervalMs: 2000,
            maxAttempts: 400,
            onDone: (status) => {
                if (ui.status) ui.status.hidden = true;
                this.renderReport(status, ui);
                if (ui.result) ui.result.hidden = false;
                window.app.toast.show("Planning report ready", { type: "success" });
            },
            onFailed: (status) => {
                if (ui.status) ui.status.hidden = true;
                if (ui.empty) ui.empty.hidden = false;
                window.app.toast.show(
                    "Planning failed: " + (status.error || "unknown error"),
                    { type: "error" },
                );
            },
            onTimeout: () => {
                if (ui.status) {
                    ui.status.querySelector(".planning-status-text").textContent =
                        "Still generating, this is taking longer than expected...";
                }
            },
        });
    }

    renderReport(status, ui) {
        if (ui.download && status.download_url) {
            ui.download.href = status.download_url;
        }
        if (!ui.report) return;
        const fresh = document.createElement("dp-content");
        fresh.className = ui.report.className;
        fresh.setAttribute("data-planning-report", "");
        fresh.textContent = status.markdown || "";
        ui.report.replaceWith(fresh);
    }
}
