/**
 * Pro-Trial-Expiry-Cron
 *
 * Läuft alle 6h. Findet alle Profiles deren `pro_trial_expires_at` abgelaufen
 * ist und die noch auf `plan = 'pro'` stehen.
 *
 * Revoke-Logik (CONSERVATIVE-Fallback):
 *   - Wenn `stripeSubId` IS NULL → revoke (zurück auf 'free')
 *   - Wenn `stripeSubId` gesetzt → NICHT revoken (User hat während Trial
 *     upgraded ODER hatte schon Stripe-Abo). Stripe-Webhook hält den State,
 *     der Trial läuft formal aus, der Abo-Plan überdauert.
 *
 * TODO (siehe project_demographic_pro_trial_reward.md): Stripe-API-Sync
 * (subscription.status='active') als zusätzliche Sicherheit. Aktuell
 * stripeSubId-presence als Indikator (kann stale sein). Wenn das Probleme
 * macht: stripe.subscriptions.retrieve(subId) hinzufügen.
 *
 * Memory: project_demographic_pro_trial_reward.md
 */
import { consola } from "consola";

const SIX_HOURS = 6 * 60 * 60 * 1000;

export default defineNitroPlugin((nitro) => {
  if (import.meta.dev) {
    consola.info("[pro-trial-cron] Skipping cron in dev mode");
    return;
  }

  consola.info("[pro-trial-cron] Starting (6h interval)");

  // Initial run after 60s (let server boot)
  const initialTimer = setTimeout(() => {
    runRevoke().catch(() => {});
  }, 60_000);

  const interval = setInterval(() => {
    runRevoke().catch(() => {});
  }, SIX_HOURS);

  nitro.hooks.hook("close", () => {
    clearTimeout(initialTimer);
    clearInterval(interval);
  });
});

async function runRevoke() {
  try {
    const db = usePrisma();
    const now = new Date();

    // Find expired trials still on 'pro' (or 'standard' legacy)
    const expired = await db.profile.findMany({
      where: {
        proTrialExpiresAt: { lt: now, not: null },
        plan: { in: ["pro", "standard"] },
      },
      select: {
        id: true,
        stripeSubId: true,
        proTrialExpiresAt: true,
      },
    });

    if (expired.length === 0) {
      consola.info("[pro-trial-cron] No expired trials");
      return;
    }

    let revoked = 0;
    let kept = 0;

    for (const p of expired) {
      // CONSERVATIVE: any stripeSubId presence keeps the user on pro
      if (p.stripeSubId) {
        kept++;
        continue;
      }
      try {
        await db.profile.update({
          where: { id: p.id },
          data: { plan: "free" },
        });
        revoked++;
      } catch (err: any) {
        consola.error(
          `[pro-trial-cron] Failed to revoke user ${p.id}:`,
          err?.message ?? err,
        );
      }
    }

    consola.success(
      `[pro-trial-cron] revoked ${revoked} users from trial-pro, kept ${kept} (Stripe-Abo)`,
    );
  } catch (err: any) {
    consola.error("[pro-trial-cron] run failed:", err?.message ?? err);
  }
}
