import { loadCredentials } from "../lib/credentials.js";
import { sendEmail } from "../lib/smtp.js";
import { getSession } from "../lib/neo4j.js";
/**
 * Strip duplicate Re:/RE:/re: prefixes and prepend a single Re:.
 */
function replySubject(subject) {
    const stripped = subject.replace(/^(Re:\s*)+/i, "").trim();
    return `Re: ${stripped || "(no subject)"}`;
}
export async function emailReply(params) {
    const result = await loadCredentials(params.accountId);
    if ("error" in result)
        throw new Error(result.error);
    const { config, password } = result.credentials;
    // Look up the original email in the graph by messageId
    const session = getSession();
    try {
        const queryResult = await session.run(`MATCH (e:Email {messageId: $messageId, accountId: $accountId})
       RETURN e.messageId AS messageId,
              e.fromAddress AS fromAddress,
              e.toAddresses AS toAddresses,
              e.ccAddresses AS ccAddresses,
              e.subject AS subject`, { messageId: params.messageId, accountId: params.accountId });
        if (queryResult.records.length === 0) {
            throw new Error(`No email found with Message-ID ${params.messageId}. The email may not have been fetched yet — emails are stored by the background polling job.`);
        }
        const record = queryResult.records[0];
        const originalMessageId = record.get("messageId");
        const originalFrom = record.get("fromAddress");
        const originalTo = record.get("toAddresses") ?? [];
        const originalCc = record.get("ccAddresses") ?? [];
        const originalSubject = record.get("subject") ?? "(no subject)";
        if (!originalMessageId) {
            throw new Error("Cannot reply — the original email has no Message-ID header. This can happen with malformed messages from some servers.");
        }
        // Guard: don't reply to own messages
        const agentAddr = config.agentAddress.toLowerCase();
        if (originalFrom.toLowerCase() === agentAddr) {
            throw new Error("Cannot reply to a message sent from the agent's own address.");
        }
        // Build recipient list
        let to;
        if (params.replyAll) {
            // Union of original sender + TO + CC, minus the agent's own address (case-insensitive)
            const all = [originalFrom, ...originalTo, ...originalCc];
            const filtered = [...new Set(all)].filter((a) => a.toLowerCase() !== agentAddr);
            to = filtered.join(", ");
        }
        else {
            to = originalFrom;
        }
        if (!to) {
            throw new Error("Cannot reply — no valid recipients after filtering the agent's own address.");
        }
        // Send the reply with threading headers
        let sentMessageId;
        try {
            ({ messageId: sentMessageId } = await sendEmail(config, password, {
                to,
                subject: replySubject(originalSubject),
                body: params.body,
                html: params.html,
                inReplyTo: originalMessageId,
                references: originalMessageId,
            }));
        }
        catch (smtpErr) {
            const smtpMsg = smtpErr instanceof Error ? smtpErr.message : String(smtpErr);
            // Add alias diagnostic only for SMTP failures
            if (config.agentAddress !== config.email) {
                throw new Error(`${smtpMsg} — Note: sending as ${config.agentAddress} (authenticated as ${config.email}). If your provider doesn't allow sending as this alias, check your catchall or alias settings.`);
            }
            throw smtpErr;
        }
        const replyType = params.replyAll ? "Reply-all" : "Reply";
        return `${replyType} sent to ${to} (Message-ID: ${sentMessageId})`;
    }
    finally {
        await session.close();
    }
}
//# sourceMappingURL=email-reply.js.map