import type { MinionPluginApi } from "../../../src/plugins/types.js";

export interface Destination {
  channel: string;
  accountId?: string;
  to: string;
  label?: string;
}

export interface DeliveryReport {
  total: number;
  successCount: number;
  perDestination: Array<{ destination: Destination; ok: boolean; error?: string }>;
}

type Sender = (to: string, text: string, opts: Record<string, unknown>) => Promise<unknown>;

const CHANNEL_METHOD_NAMES: Record<string, string> = {
  whatsapp: "sendMessageWhatsApp",
  telegram: "sendMessageTelegram",
  discord: "sendMessageDiscord",
};

function resolveSender(api: MinionPluginApi, channel: string): Sender | null {
  const channelRegistry = api.runtime.channel as unknown as Record<string, Record<string, unknown>>;
  const ch = channelRegistry[channel];
  if (!ch) return null;
  const key =
    CHANNEL_METHOD_NAMES[channel] ??
    `sendMessage${channel.charAt(0).toUpperCase() + channel.slice(1)}`;
  const fn = ch[key];
  return typeof fn === "function" ? (fn as Sender) : null;
}

export async function sendAlerts(
  api: MinionPluginApi,
  destinations: Destination[],
  text: string,
): Promise<DeliveryReport> {
  const results = await Promise.all(
    destinations.map(async (d) => {
      const sender = resolveSender(api, d.channel);
      if (!sender) {
        api.logger.warn(`complaint-listener: unknown channel '${d.channel}' for destination ${d.to}`);
        return { destination: d, ok: false, error: "unknown_channel" };
      }
      try {
        const opts: Record<string, unknown> = { verbose: false };
        if (d.accountId) opts.accountId = d.accountId;
        if (d.channel === "telegram") opts.textMode = "markdown";
        await sender(d.to, text, opts);
        return { destination: d, ok: true };
      } catch (err) {
        api.logger.error(`complaint-listener: send to ${d.channel}:${d.to} failed: ${String(err)}`);
        return { destination: d, ok: false, error: String(err) };
      }
    }),
  );
  return {
    total: destinations.length,
    successCount: results.filter((r) => r.ok).length,
    perDestination: results,
  };
}
