/**
 * Outbox view modal — lists .ltr files currently queued on disk.
 * Pink rows = local-only, not yet reconciled with the server.
 * Clicking the status-bar queue pill opens this.
 */
import { listQueuedOutgoing, cancelQueuedOutgoing } from "../lib/api-client.js";
let isOpen = false;
export async function openOutboxView() {
    if (isOpen)
        return;
    isOpen = true;
    const backdrop = document.createElement("div");
    backdrop.className = "mailx-modal-backdrop";
    const panel = document.createElement("div");
    panel.className = "mailx-modal mailx-modal-wide";
    panel.innerHTML = `
        <div class="mailx-modal-title">
            <span class="mailx-modal-title-text">Outbox — Local Queue</span>
            <button type="button" class="mailx-modal-close" id="ob-close" title="Close (Esc)" aria-label="Close">&times;</button>
        </div>
        <div class="ob-info">Messages waiting to be sent. Pink rows are local-only until the server accepts them. Click Cancel to drop a queued message.</div>
        <div class="ob-list" id="ob-list">Loading…</div>
        <div class="mailx-modal-buttons">
            <span class="mailx-modal-spacer"></span>
            <button type="button" class="mailx-modal-btn" data-action="refresh">Refresh</button>
            <button type="button" class="mailx-modal-btn" data-action="close">Close</button>
        </div>`;
    backdrop.appendChild(panel);
    document.body.appendChild(backdrop);
    const listEl = panel.querySelector("#ob-list");
    const renderList = (items) => {
        if (items.length === 0) {
            listEl.innerHTML = `<div class="ob-empty">Outbox is clean — no messages queued.</div>`;
            return;
        }
        const fmtDate = (ms) => new Date(ms).toLocaleString();
        const ageStr = (ms) => {
            const sec = Math.max(0, Math.round((Date.now() - ms) / 1000));
            if (sec < 60)
                return `${sec}s`;
            if (sec < 3600)
                return `${Math.round(sec / 60)}m`;
            return `${Math.round(sec / 3600)}h`;
        };
        listEl.innerHTML = items.map((m, i) => {
            // A claim that's "young" (under 60 s) is presumed actively
            // sending. Older claims are stuck — server hung mid-SMTP,
            // worker crashed, PID recycled. Cancel must always be
            // available either way: the user knows their intent. A
            // brief in-flight cancel may cross the SMTP-send window
            // (rare; <60s of risk), in which case the X-Mailx-Retry +
            // Message-ID dedup on the receiving end catches the dup.
            const claimAge = m.claimed ? ageStr(m.createdAt) : "";
            const stuckClaim = m.claimed && (Date.now() - m.createdAt) > 60_000;
            const claimBadge = !m.claimed
                ? ""
                : stuckClaim
                    ? `<span class="ob-badge ob-stuck" title="Claim is older than 60 s — likely stuck. Cancel will drop it.">stuck (${claimAge})</span>`
                    : `<span class="ob-badge ob-claimed" title="Sending now on this host">sending… (${claimAge})</span>`;
            return `
            <div class="ob-row ob-pink" data-idx="${i}">
                <div class="ob-row-hdr">
                    <span class="ob-acct">${escapeHtml(m.accountId)}</span>
                    <span class="ob-subject">${escapeHtml(m.subject || "(no subject)")}</span>
                    <span class="ob-created">${fmtDate(m.createdAt)}</span>
                    ${claimBadge}
                    ${m.attempts > 0 ? `<span class="ob-badge ob-retry" title="Retry attempts made so far">retry ×${m.attempts}</span>` : ""}
                </div>
                <div class="ob-row-meta">
                    <span class="ob-from">${escapeHtml(m.from || "")}</span>
                    → <span class="ob-to">${escapeHtml(m.to || "")}</span>
                    ${m.cc ? ` · Cc: ${escapeHtml(m.cc)}` : ""}
                    <span class="ob-size">· ${(m.sizeBytes / 1024).toFixed(1)}kB</span>
                </div>
                <div class="ob-row-path">${escapeHtml(m.path)}</div>
                <div class="ob-row-actions">
                    <button type="button" class="ob-cancel">Cancel</button>
                </div>
            </div>`;
        }).join("");
        listEl.querySelectorAll(".ob-row").forEach((row, idx) => {
            row.querySelector(".ob-cancel").addEventListener("click", async () => {
                const m = items[idx];
                const warning = m.claimed
                    ? `This message is currently in flight to the SMTP server.\nIf SMTP already finished, the recipient may have received it.\nMessage-ID dedup catches the duplicate side; cancel is still safe.\n\nDrop anyway?\n\nTo: ${m.to}\nSubject: ${m.subject}`
                    : `Drop this queued message?\n\nTo: ${m.to}\nSubject: ${m.subject}`;
                if (!confirm(warning))
                    return;
                try {
                    await cancelQueuedOutgoing(m.path);
                    await reload();
                }
                catch (e) {
                    alert(`Cancel failed: ${e?.message || e}`);
                }
            });
        });
    };
    const reload = async () => {
        try {
            const items = await listQueuedOutgoing();
            renderList(items || []);
        }
        catch (e) {
            listEl.innerHTML = `<div class="ob-empty">Load failed: ${escapeHtml(e?.message || String(e))}</div>`;
        }
    };
    const close = () => {
        backdrop.remove();
        document.removeEventListener("keydown", onKey, true);
        isOpen = false;
    };
    const onKey = (e) => {
        if (e.key === "Escape") {
            e.stopPropagation();
            e.preventDefault();
            close();
        }
    };
    document.addEventListener("keydown", onKey, true);
    panel.querySelector("#ob-close").addEventListener("click", close);
    panel.querySelector('[data-action="close"]').addEventListener("click", close);
    panel.querySelector('[data-action="refresh"]').addEventListener("click", reload);
    backdrop.addEventListener("mousedown", (e) => { if (e.target === backdrop)
        close(); });
    await reload();
}
function escapeHtml(s) {
    return s.replace(/[&<>"']/g, c => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", "\"": "&quot;", "'": "&#39;" }[c]));
}
//# sourceMappingURL=outbox-view.js.map