/**
 * Address book modal — list / search / edit / delete contacts.
 * Sources: 'sent' (added on outgoing), 'received' (seeded from message senders),
 * 'manual' (added directly here), 'google' (Google Contacts sync).
 */
import { listContacts, upsertContact, deleteContact } from "../lib/api-client.js";
let isOpen = false;
export async function openAddressBook(prefillSearch) {
    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">Address Book</span>
            <button type="button" class="mailx-modal-close" id="ab-close" title="Close (Esc)" aria-label="Close">&times;</button>
        </div>
        <div class="ab-toolbar">
            <input type="search" id="ab-search" class="mailx-modal-input" placeholder="Search name or email…" autocomplete="off">
            <button type="button" class="mailx-modal-btn mailx-modal-btn-primary" id="ab-new">+ New contact</button>
        </div>
        <div class="ab-count" id="ab-count"></div>
        <div class="ab-list" id="ab-list">Loading…</div>
        <div class="mailx-modal-buttons">
            <span class="mailx-modal-spacer"></span>
            <button type="button" class="mailx-modal-btn" data-action="close">Close</button>
        </div>`;
    backdrop.appendChild(panel);
    document.body.appendChild(backdrop);
    const searchInput = panel.querySelector("#ab-search");
    const listEl = panel.querySelector("#ab-list");
    const countEl = panel.querySelector("#ab-count");
    let editingEmail = null;
    const render = (items, total) => {
        countEl.textContent = total === items.length
            ? `${total} contact${total === 1 ? "" : "s"}`
            : `Showing ${items.length} of ${total}`;
        if (items.length === 0) {
            listEl.innerHTML = `<div class="ab-empty">No contacts match.</div>`;
            return;
        }
        const fmtDate = (ms) => {
            if (!ms)
                return "";
            const d = new Date(ms);
            const now = new Date();
            return d.getFullYear() === now.getFullYear()
                ? d.toLocaleDateString(undefined, { month: "short", day: "numeric" })
                : d.toLocaleDateString();
        };
        listEl.innerHTML = `
            <div class="ab-row ab-header">
                <span class="ab-name">Name</span>
                <span class="ab-email">Email</span>
                <span class="ab-source">Source</span>
                <span class="ab-count-cell" title="Times sent to">×</span>
                <span class="ab-last">Last</span>
                <span class="ab-actions"></span>
            </div>` + items.map(c => `
            <div class="ab-row" data-email="${escapeAttr(c.email)}">
                <span class="ab-name">${escapeHtml(c.name || "")}</span>
                <span class="ab-email">${escapeHtml(c.email)}</span>
                <span class="ab-source">${escapeHtml(c.source)}</span>
                <span class="ab-count-cell">${c.useCount || 0}</span>
                <span class="ab-last">${fmtDate(c.lastUsed)}</span>
                <span class="ab-actions">
                    <button type="button" class="ab-edit" title="Edit name">✎</button>
                    <button type="button" class="ab-del" title="Delete">🗑</button>
                    <button type="button" class="ab-mail" title="Compose to">✉</button>
                </span>
            </div>`).join("");
        listEl.querySelectorAll(".ab-row[data-email]").forEach(row => {
            const email = row.dataset.email;
            const c = items.find(x => x.email === email);
            row.querySelector(".ab-edit")?.addEventListener("click", () => beginEdit(row, c));
            row.querySelector(".ab-del")?.addEventListener("click", () => doDelete(c));
            row.querySelector(".ab-mail")?.addEventListener("click", () => composeTo(c));
        });
    };
    const beginEdit = (row, c) => {
        if (editingEmail === c.email)
            return;
        editingEmail = c.email;
        const nameSpan = row.querySelector(".ab-name");
        const original = c.name || "";
        nameSpan.innerHTML = `<input type="text" value="${escapeAttr(original)}" class="ab-name-input">`;
        const inp = nameSpan.querySelector("input");
        inp.focus();
        inp.select();
        const commit = async () => {
            const newName = inp.value.trim();
            if (newName !== original) {
                try {
                    await upsertContact(newName, c.email);
                    c.name = newName;
                }
                catch (e) {
                    alert(`Update failed: ${e?.message || e}`);
                }
            }
            nameSpan.textContent = c.name || "";
            editingEmail = null;
        };
        inp.addEventListener("blur", commit);
        inp.addEventListener("keydown", (e) => {
            if (e.key === "Enter") {
                e.preventDefault();
                inp.blur();
            }
            else if (e.key === "Escape") {
                e.preventDefault();
                inp.value = original;
                inp.blur();
            }
        });
    };
    const doDelete = async (c) => {
        if (!confirm(`Delete contact "${c.name || c.email}"?`))
            return;
        try {
            await deleteContact(c.email);
            await reload();
        }
        catch (e) {
            alert(`Delete failed: ${e?.message || e}`);
        }
    };
    const composeTo = (c) => {
        const init = {
            mode: "new",
            to: [{ name: c.name || "", address: c.email }],
            cc: [], bcc: [], subject: "", bodyHtml: "",
            inReplyTo: "", references: [], accounts: [],
        };
        try {
            sessionStorage.setItem("composeInit", JSON.stringify(init));
        }
        catch { /* */ }
        document.dispatchEvent(new CustomEvent("mailx-compose", { detail: { mode: "new" } }));
        close();
    };
    let reloadDebounce;
    const reload = async () => {
        try {
            const r = await listContacts(searchInput.value, 1, 200);
            render(r.items, r.total);
        }
        catch (e) {
            listEl.innerHTML = `<div class="ab-empty">Load failed: ${escapeHtml(e?.message || String(e))}</div>`;
        }
    };
    const scheduleReload = () => {
        if (reloadDebounce)
            window.clearTimeout(reloadDebounce);
        reloadDebounce = window.setTimeout(reload, 200);
    };
    panel.querySelector("#ab-new")?.addEventListener("click", async () => {
        const email = prompt("Email address:");
        if (!email)
            return;
        const name = prompt("Display name (optional):") || "";
        try {
            await upsertContact(name, email.trim());
            await reload();
        }
        catch (e) {
            alert(`Add failed: ${e?.message || e}`);
        }
    });
    searchInput.addEventListener("input", scheduleReload);
    // "Open in contacts" from the viewer's address right-click lands here with
    // the address prefilled, so the list opens already filtered to that person.
    if (prefillSearch)
        searchInput.value = prefillSearch;
    const close = () => {
        if (reloadDebounce)
            window.clearTimeout(reloadDebounce);
        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("#ab-close").addEventListener("click", close);
    panel.querySelector('[data-action="close"]').addEventListener("click", close);
    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]));
}
function escapeAttr(s) { return escapeHtml(s); }
//# sourceMappingURL=address-book.js.map