import type { Server as SocketServer } from 'socket.io';
import { sql } from '../db.js';
import { messagingService } from './messagingService.js';
import { channelService } from './channelService.js';
import { isUnsupportedCapabilityError, resolveWhatsAppTarget } from './channelProviderRules.js';
import { auditService } from './auditService.js';
import { sendSmtpMail } from './emailService.js';
import { emitMessageNew } from './messageEmitService.js';

/** Deliver automated text on portal, email, or WhatsApp channels. */
export async function sendAutomatedOutbound(params: {
  io: SocketServer;
  ticketId: string;
  channelId: string;
  contactPhone: string;
  text: string;
}): Promise<void> {
  const { io, ticketId, channelId, contactPhone, text } = params;

  if (contactPhone.startsWith('portal:')) {
    const message = await messagingService.appendMessage(ticketId, 'outbound', text, null, undefined, 'portal');
    await auditService.log(null, 'system', 'message.automated', 'message', message.id, { ticketId });
    await emitMessageNew(io, ticketId, message);
    return;
  }

  if (contactPhone.startsWith('email:') && contactPhone.includes('@')) {
    const to = contactPhone.slice(6);
    const sent = await sendSmtpMail({
      to,
      subject: 'Re: Your support request',
      text,
    });
    if (!sent.ok) {
      await auditService.log(null, 'system', 'message.automated_failed', 'message', ticketId, {
        ticketId,
        error: sent.error,
      });
      return;
    }
    const message = await messagingService.appendMessage(ticketId, 'outbound', text, null, undefined, 'email');
    await auditService.log(null, 'system', 'message.automated', 'message', message.id, { ticketId });
    await emitMessageNew(io, ticketId, message);
    return;
  }

  // Group tickets: deliver into the WhatsApp group, not the sender's 1:1 chat
  const [ticketRow] = await sql<[{ wa_group_jid: string | null }]>`
    SELECT wa_group_jid FROM tickets WHERE id = ${ticketId} LIMIT 1
  `;
  let waTarget = contactPhone;
  if (ticketRow?.wa_group_jid?.trim()) {
    const channel = await channelService.getById(channelId);
    if (!channel) throw Object.assign(new Error('Channel not found'), { statusCode: 404 });
    try {
      waTarget = resolveWhatsAppTarget(channel, ticketRow.wa_group_jid, contactPhone);
    } catch (err) {
      if (!isUnsupportedCapabilityError(err)) throw err;
      // Provider cannot address groups: skip before any message is stored or sent
      await auditService.log(null, 'system', 'message.automated_failed', 'ticket', ticketId, {
        ticketId,
        error: String(err),
      });
      return;
    }
  }

  const message = await messagingService.appendMessage(ticketId, 'outbound', text, null);

  try {
    const waMessageId = await channelService.sendMessage(channelId, waTarget, text);
    if (waMessageId) {
      await sql`UPDATE messages SET wa_message_id = ${waMessageId} WHERE id = ${message.id}`;
      message.wa_message_id = waMessageId;
    }
    await auditService.log(null, 'system', 'message.automated', 'message', message.id, { ticketId });
    await emitMessageNew(io, ticketId, message);
  } catch (err) {
    await auditService.log(null, 'system', 'message.automated_failed', 'message', message.id, {
      ticketId,
      error: String(err),
    });
  }
}
