import { loadCredentials } from "../lib/credentials.js";
import { sendEmail } from "../lib/smtp.js";
import { fetchEnvelopeByMessageId } from "../lib/imap.js";
import { resolveOutboundAttachments, formatAttachNote } from "../lib/attachment-resolve.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;
    // Validate attachment paths before any IMAP work so a bad path fails fast
    // with a clean error and no envelope lookup or send is attempted.
    const attachments = resolveOutboundAttachments(process.env.ACCOUNT_DIR, params.attachments);
    // Resolve the original message via IMAP (the graph no longer stores
    // per-message envelopes — see Task 445).
    const envelope = await fetchEnvelopeByMessageId(config, password, params.messageId);
    if (!envelope) {
        throw new Error(`No email found with Message-ID ${params.messageId} on the IMAP server. The message may have been deleted, moved out of INBOX/Sent, or never delivered.`);
    }
    const originalMessageId = envelope.messageId;
    const originalFrom = envelope.fromAddress;
    const originalTo = envelope.toAddresses;
    const originalCc = envelope.ccAddresses;
    const originalSubject = envelope.subject || "(no subject)";
    // 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,
            attachments,
        }));
    }
    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}${formatAttachNote(attachments)} (Message-ID: ${sentMessageId})`;
}
//# sourceMappingURL=email-reply.js.map