import { prisma } from "@/lib/prisma";
import { Prisma } from "@/app/generated/prisma/client";
import type { EmailJobStatus } from "@/app/generated/prisma/enums";

/** Filter untuk halaman admin email log. Keduanya opsional, match `contains`. */
export interface EmailLogFilters {
  to?: string;
  template?: string;
}

const LIST_LIMIT = 100;

function buildWhere<T extends { to?: unknown; template?: unknown }>(
  filters: EmailLogFilters
): T {
  const where = {} as T;
  if (filters.to) {
    (where as { to?: unknown }).to = {
      contains: filters.to,
      mode: "insensitive",
    };
  }
  if (filters.template) {
    (where as { template?: unknown }).template = {
      contains: filters.template,
      mode: "insensitive",
    };
  }
  return where;
}

export const emailRepo = {
  /** EmailJob (retry queue) per status — terbaru dulu. */
  async listJobs(statuses: EmailJobStatus[], filters: EmailLogFilters) {
    const where = buildWhere<Prisma.EmailJobWhereInput>(filters);
    where.status = { in: statuses };
    return prisma.emailJob.findMany({
      where,
      orderBy: { updatedAt: "desc" },
      take: LIST_LIMIT,
    });
  },

  /** EmailSent (log email berhasil terkirim) — terbaru dulu. */
  async listSent(filters: EmailLogFilters) {
    const where = buildWhere<Prisma.EmailSentWhereInput>(filters);
    return prisma.emailSent.findMany({
      where,
      orderBy: { sentAt: "desc" },
      take: LIST_LIMIT,
    });
  },

  /**
   * Statistik kesehatan pengiriman email — dipakai kartu ringkasan
   * `/admin/emails` dan `/admin/system`.
   * - `queued`     : job menunggu dikirim (PENDING/PROCESSING).
   * - `failed24h`  : job gagal dalam 24 jam terakhir.
   * - `deadLetter` : job gagal yang sudah habis 5 attempt — cron berhenti
   *                  retry, butuh aksi manual admin.
   */
  async stats() {
    const since24h = new Date(Date.now() - 24 * 60 * 60 * 1000);
    const [queued, failed24h, deadLetter] = await Promise.all([
      prisma.emailJob.count({
        where: { status: { in: ["PENDING", "PROCESSING"] } },
      }),
      prisma.emailJob.count({
        where: { status: "FAILED", updatedAt: { gte: since24h } },
      }),
      prisma.emailJob.count({
        where: { status: "FAILED", attempts: { gte: 5 } },
      }),
    ]);
    return { queued, failed24h, deadLetter };
  },
};
