/**
 * Scheduler für automatische Geburtstagsgrüße.
 *
 * Läuft täglich um 08:00 Uhr und sendet Grüße an alle Kunden mit:
 *   - Geburtstag = heute
 *   - autoBirthdayGreeting = true
 *   - autoBirthdayChannel ist gesetzt (aktuell nur 'email' automatisiert)
 *   - lastBirthdayGreetingYear != aktuelles Jahr (verhindert Doppel-Versand)
 */
import cron from 'node-cron';
import prisma from '../lib/prisma.js';
import { sendEmail, SmtpCredentials } from './smtpService.js';
import { getSystemEmailCredentials } from './emailProvider/emailProviderService.js';
import * as birthdayService from './birthday.service.js';

async function runDailyBirthdayGreetings(): Promise<void> {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const thisYear = today.getFullYear();
  const month = today.getMonth() + 1; // Prisma-Raw-SQL ist 1-indexed
  const day = today.getDate();

  console.log(
    `[BirthdayScheduler] Suche Kunden mit Geburtstag ${day}.${month}., Auto-Versand aktiv …`,
  );

  // Kunden mit heutigem Geburtstag + Auto-Versand + dieses Jahr noch nicht gesendet
  const candidates = await prisma.$queryRaw<
    Array<{
      id: number;
      firstName: string;
      lastName: string;
      email: string | null;
      salutation: string | null;
      useInformalAddress: boolean;
      birthDate: Date;
      autoBirthdayChannel: string | null;
    }>
  >`
    SELECT id, firstName, lastName, email, salutation, useInformalAddress, birthDate, autoBirthdayChannel
    FROM Customer
    WHERE autoBirthdayGreeting = 1
      AND birthDate IS NOT NULL
      AND MONTH(birthDate) = ${month}
      AND DAY(birthDate) = ${day}
      AND (lastBirthdayGreetingYear IS NULL OR lastBirthdayGreetingYear != ${thisYear})
  `;

  if (candidates.length === 0) {
    console.log('[BirthdayScheduler] Keine passenden Kunden heute.');
    return;
  }

  console.log(`[BirthdayScheduler] ${candidates.length} Kunde(n) gefunden – sende Grüße.`);

  // System-E-Mail-Credentials einmal laden
  const systemEmail = await getSystemEmailCredentials();
  if (!systemEmail) {
    console.error(
      '[BirthdayScheduler] Keine System-E-Mail konfiguriert – kann keine Grüße versenden.',
    );
    return;
  }

  const smtpCreds: SmtpCredentials = {
    host: systemEmail.smtpServer,
    port: systemEmail.smtpPort,
    user: systemEmail.emailAddress,
    password: systemEmail.password,
    encryption: systemEmail.smtpEncryption,
    allowSelfSignedCerts: systemEmail.allowSelfSignedCerts,
  };

  let sent = 0;
  let skipped = 0;

  for (const c of candidates) {
    const channel = c.autoBirthdayChannel || 'email';

    // Aktuell nur Email automatisch – Messenger brauchen Browser-Klick
    if (channel !== 'email') {
      console.log(
        `[BirthdayScheduler] Kunde #${c.id} (${c.firstName} ${c.lastName}): Kanal "${channel}" nicht automatisierbar, übersprungen.`,
      );
      skipped++;
      continue;
    }

    if (!c.email) {
      console.log(
        `[BirthdayScheduler] Kunde #${c.id} (${c.firstName} ${c.lastName}): keine E-Mail hinterlegt, übersprungen.`,
      );
      skipped++;
      continue;
    }

    const age = thisYear - new Date(c.birthDate).getFullYear();
    const { subject, html } = birthdayService.buildBirthdayGreetingText(
      {
        firstName: c.firstName,
        lastName: c.lastName,
        salutation: c.salutation,
        useInformalAddress: c.useInformalAddress,
      },
      age,
    );

    try {
      const result = await sendEmail(
        smtpCreds,
        systemEmail.emailAddress,
        { to: c.email, subject, html },
        { context: 'birthday-greeting-auto', customerId: c.id, triggeredBy: 'cron' },
      );

      if (result.success) {
        // Marker setzen damit nächstes Jahr wieder läuft, dieses Jahr aber nicht nochmal
        await prisma.customer.update({
          where: { id: c.id },
          data: { lastBirthdayGreetingYear: thisYear },
        });
        sent++;
        console.log(
          `[BirthdayScheduler] ✓ Kunde #${c.id} (${c.firstName} ${c.lastName}): Gruß gesendet.`,
        );
      } else {
        console.error(
          `[BirthdayScheduler] ✗ Kunde #${c.id}: Sendfehler: ${result.error}`,
        );
        skipped++;
      }
    } catch (err) {
      console.error(`[BirthdayScheduler] ✗ Kunde #${c.id}: Exception:`, err);
      skipped++;
    }
  }

  console.log(
    `[BirthdayScheduler] Fertig: ${sent} versendet, ${skipped} übersprungen von ${candidates.length} Kandidaten.`,
  );
}

/**
 * Scheduler starten. Läuft täglich um 08:00 in lokaler Server-Zeit.
 * Zusätzlich: ein Test-Lauf 30 Sekunden nach Server-Start, aber nur wenn heute schon jemand Geburtstag hat
 * (sonst passiert eh nichts). So können wir bei Ausfall am Tag X direkt beim nächsten Boot nachholen.
 */
export function startBirthdayScheduler(): void {
  // Täglich um 08:00
  cron.schedule('0 8 * * *', () => {
    runDailyBirthdayGreetings().catch((err) =>
      console.error('[BirthdayScheduler] Daily run failed:', err),
    );
  });

  // Einmal 30 Sekunden nach Start (Catch-up bei Ausfall)
  setTimeout(() => {
    runDailyBirthdayGreetings().catch((err) =>
      console.error('[BirthdayScheduler] Catch-up run failed:', err),
    );
  }, 30_000);

  console.log('[BirthdayScheduler] Gestartet – täglich um 08:00 + Catch-up nach 30s');
}

/**
 * Für manuelles Triggern (z.B. aus Debug-Endpoint).
 */
export { runDailyBirthdayGreetings };
