import { randomUUID } from "node:crypto";
import { loadConfig } from "../config/config.js";
import { resolveMarkdownTableMode } from "../config/markdown-tables.js";
import { getChildLogger } from "../logging/logger.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import { convertMarkdownTables } from "../markdown/tables.js";
import { markdownToWhatsApp } from "../markdown/whatsapp.js";
import { normalizePollInput } from "../polls.js";
import { toWhatsappJid } from "../utils.js";
import { requireActiveWebListener } from "./active-listener.js";
import { loadWebMedia } from "./media.js";
const outboundLog = createSubsystemLogger("gateway/channels/whatsapp").child("outbound");
export async function sendMessageWhatsApp(to, body, options) {
    let text = body;
    const correlationId = randomUUID();
    const startedAt = Date.now();
    const { listener: active, accountId: resolvedAccountId } = requireActiveWebListener(options.accountId);
    const cfg = loadConfig();
    const tableMode = resolveMarkdownTableMode({
        cfg,
        channel: "whatsapp",
        accountId: resolvedAccountId ?? options.accountId,
    });
    text = convertMarkdownTables(text ?? "", tableMode);
    text = markdownToWhatsApp(text);
    const logger = getChildLogger({
        module: "web-outbound",
        correlationId,
        to,
    });
    try {
        const jid = toWhatsappJid(to);
        let mediaBuffer;
        let mediaType;
        let documentFileName;
        if (options.mediaUrl) {
            const media = await loadWebMedia(options.mediaUrl);
            const caption = text || undefined;
            mediaBuffer = media.buffer;
            mediaType = media.contentType;
            if (media.kind === "audio") {
                // WhatsApp expects explicit opus codec for PTT voice notes.
                mediaType =
                    media.contentType === "audio/ogg"
                        ? "audio/ogg; codecs=opus"
                        : (media.contentType ?? "application/octet-stream");
            }
            else if (media.kind === "video") {
                text = caption ?? "";
            }
            else if (media.kind === "image") {
                text = caption ?? "";
            }
            else {
                text = caption ?? "";
                documentFileName = media.fileName;
            }
        }
        outboundLog.info(`Sending message -> ${jid}${options.mediaUrl ? " (media)" : ""}`);
        logger.info({ jid, hasMedia: Boolean(options.mediaUrl) }, "sending message");
        await active.sendComposingTo(to);
        const hasExplicitAccountId = Boolean(options.accountId?.trim());
        const accountId = hasExplicitAccountId ? resolvedAccountId : undefined;
        const sendOptions = options.gifPlayback || accountId || documentFileName
            ? {
                ...(options.gifPlayback ? { gifPlayback: true } : {}),
                ...(documentFileName ? { fileName: documentFileName } : {}),
                accountId,
            }
            : undefined;
        const result = sendOptions
            ? await active.sendMessage(to, text, mediaBuffer, mediaType, sendOptions)
            : await active.sendMessage(to, text, mediaBuffer, mediaType);
        const messageId = result?.messageId ?? "unknown";
        const durationMs = Date.now() - startedAt;
        outboundLog.info(`Sent message ${messageId} -> ${jid}${options.mediaUrl ? " (media)" : ""} (${durationMs}ms)`);
        logger.info({ jid, messageId }, "sent message");
        return { messageId, toJid: jid };
    }
    catch (err) {
        logger.error({ err: String(err), to, hasMedia: Boolean(options.mediaUrl) }, "failed to send via web session");
        throw err;
    }
}
export async function sendReactionWhatsApp(chatJid, messageId, emoji, options) {
    const correlationId = randomUUID();
    const { listener: active } = requireActiveWebListener(options.accountId);
    const logger = getChildLogger({
        module: "web-outbound",
        correlationId,
        chatJid,
        messageId,
    });
    try {
        const jid = toWhatsappJid(chatJid);
        outboundLog.info(`Sending reaction "${emoji}" -> message ${messageId}`);
        logger.info({ chatJid: jid, messageId, emoji }, "sending reaction");
        await active.sendReaction(chatJid, messageId, emoji, options.fromMe ?? false, options.participant);
        outboundLog.info(`Sent reaction "${emoji}" -> message ${messageId}`);
        logger.info({ chatJid: jid, messageId, emoji }, "sent reaction");
    }
    catch (err) {
        logger.error({ err: String(err), chatJid, messageId, emoji }, "failed to send reaction via web session");
        throw err;
    }
}
export async function sendPollWhatsApp(to, poll, options) {
    const correlationId = randomUUID();
    const startedAt = Date.now();
    const { listener: active } = requireActiveWebListener(options.accountId);
    const logger = getChildLogger({
        module: "web-outbound",
        correlationId,
        to,
    });
    try {
        const jid = toWhatsappJid(to);
        const normalized = normalizePollInput(poll, { maxOptions: 12 });
        outboundLog.info(`Sending poll -> ${jid}: "${normalized.question}"`);
        logger.info({
            jid,
            question: normalized.question,
            optionCount: normalized.options.length,
            maxSelections: normalized.maxSelections,
        }, "sending poll");
        const result = await active.sendPoll(to, normalized);
        const messageId = result?.messageId ?? "unknown";
        const durationMs = Date.now() - startedAt;
        outboundLog.info(`Sent poll ${messageId} -> ${jid} (${durationMs}ms)`);
        logger.info({ jid, messageId }, "sent poll");
        return { messageId, toJid: jid };
    }
    catch (err) {
        logger.error({ err: String(err), to, question: poll.question }, "failed to send poll via web session");
        throw err;
    }
}
