import nodemailer from "nodemailer";

import { config } from "./config.js";
import { createLogger } from "./logger.js";
import type { RuntimeSettings } from "./runtimeSettings.js";

const logger = createLogger(config.logLevel);

async function sendEmail(subject: string, body: string, settings: RuntimeSettings): Promise<void> {
  if (!settings.mailServer || !settings.mailFrom || !settings.mailTo) {
    logger.debug("Mail configuration incomplete; skipping email alert.");
    return;
  }

  const useImplicitTls = settings.mailUseTls && settings.mailPort === 465;
  const transporter = nodemailer.createTransport({
    host: settings.mailServer,
    port: settings.mailPort ?? 587,
    secure: useImplicitTls,
    requireTLS: settings.mailUseTls && !useImplicitTls,
    auth:
      settings.mailUsername && settings.mailPassword
        ? {
            user: settings.mailUsername,
            pass: settings.mailPassword
          }
        : undefined,
    tls: settings.mailUseTls ? { minVersion: "TLSv1.2" } : undefined
  });

  await transporter.sendMail({
    from: settings.mailFrom,
    to: settings.mailTo,
    subject,
    text: body
  });
}

async function sendNtfy(subject: string, body: string, settings: RuntimeSettings): Promise<void> {
  if (!settings.ntfyServerUrl || !settings.ntfyTopic) {
    logger.debug("ntfy configuration missing; skipping push notification.");
    return;
  }

  const url = `${settings.ntfyServerUrl.replace(/\/$/, "")}/${settings.ntfyTopic}`;
  const headers: Record<string, string> = {
    Title: subject
  };
  if (settings.ntfyToken) {
    headers.Authorization = `Bearer ${settings.ntfyToken}`;
  }
  if (settings.ntfyPriority) {
    headers.Priority = settings.ntfyPriority;
  }

  const response = await fetch(url, {
    method: "POST",
    headers,
    body
  });

  if (!response.ok) {
    const text = await response.text();
    throw new Error(`ntfy responded with ${response.status}: ${text}`);
  }
}

export async function sendDeadlineNotifications(subject: string, lines: string[], settings: RuntimeSettings) {
  const message = lines.join("\n");
  const tasks: Array<Promise<void>> = [];

  if (settings.mailServer && settings.mailFrom && settings.mailTo) {
    tasks.push(
      sendEmail(subject, message, settings).then(() => {
        logger.info("Deadline alert email sent.");
      })
    );
  }

  if (settings.ntfyServerUrl && settings.ntfyTopic) {
    tasks.push(
      sendNtfy(subject, message, settings).then(() => {
        logger.info("Deadline alert pushed via ntfy.");
      })
    );
  }

  if (tasks.length === 0) {
    logger.debug("No notification channels configured; skipping alerts.");
    return;
  }

  try {
    await Promise.all(tasks);
  } catch (error) {
    logger.error("Failed to deliver one or more notifications", error);
  }
}

export async function sendTestEmail(settings: RuntimeSettings): Promise<void> {
  if (!settings.mailServer || !settings.mailFrom || !settings.mailTo) {
    throw new Error("E-Mail-Konfiguration unvollständig");
  }
  await sendEmail("Contracts Companion Test", "Dies ist eine Testbenachrichtigung.", settings);
}

export async function sendTestNtfy(settings: RuntimeSettings): Promise<void> {
  if (!settings.ntfyServerUrl || !settings.ntfyTopic) {
    throw new Error("ntfy-Konfiguration unvollständig");
  }
  await sendNtfy("Contracts Companion Test", "Dies ist eine Testbenachrichtigung.", settings);
}
