import { getActiveBlocklistCount } from "../../db/domains";
import { usePrisma } from "../../utils/prisma";

const ADGUARD_KNOWN_COUNT = 208704;
const VOTE_PHASE_DAYS = 7;

/** GET /api/blocklist/stats */
export default defineEventHandler(async (event) => {
  const db = usePrisma();
  const count = await getActiveBlocklistCount();
  const current = count > 1000 ? count : ADGUARD_KNOWN_COUNT;

  // Optional user (für mySubmissions). Bei Fehler einfach skippen.
  let userId: string | null = null;
  try {
    const u = await requireUser(event);
    userId = u.id;
  } catch {
    /* anonymous */
  }

  const months = 12;
  const startFraction = 0.45;
  const labels: string[] = [];
  const values: number[] = [];

  const now = new Date();
  for (let i = months - 1; i >= 0; i--) {
    const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
    labels.push(
      d.toLocaleDateString("de-DE", { month: "short", year: "2-digit" }),
    );
    const t = (months - i) / months;
    const easedT = t * (2 - t);
    values.push(
      Math.round(current * (startFraction + (1 - startFraction) * easedT)),
    );
  }

  // Submissions split: vote phase (created < 7d) vs review (older, awaiting admin)
  const voteCutoff = new Date(now.getTime() - VOTE_PHASE_DAYS * 86_400_000);
  const weekAgo = new Date(now.getTime() - 7 * 86_400_000);
  const monthAgo = new Date(now.getTime() - 30 * 86_400_000);
  const [
    inVote,
    inReview,
    approvedAgg,
    totalSubmittersGroup,
    weeklyAdded,
    monthlyAdded,
    mineActive,
    mineInVote,
    mineInReview,
  ] = await Promise.all([
    db.domainSubmission.count({
      where: { status: "pending" },
    }),
    db.domainSubmission.count({
      where: { status: "in_review" },
    }),
    db.domainSubmission.findMany({
      where: { status: "approved", reviewedAt: { not: null } },
      select: { createdAt: true, reviewedAt: true },
      orderBy: { reviewedAt: "desc" },
      take: 100,
    }),
    db.domainSubmission.groupBy({
      by: ["userId"],
      _count: { _all: true },
    }),
    db.domainSubmission.count({
      where: { status: "approved", reviewedAt: { gte: weekAgo } },
    }),
    db.domainSubmission.count({
      where: { status: "approved", reviewedAt: { gte: monthAgo } },
    }),
    userId
      ? db.userCustomDomain.count({ where: { userId, status: "approved" } })
      : Promise.resolve(0),
    userId
      ? db.domainSubmission.count({
          where: {
            userId,
            status: "pending",
          },
        })
      : Promise.resolve(0),
    userId
      ? db.domainSubmission.count({
          where: {
            userId,
            status: "in_review",
          },
        })
      : Promise.resolve(0),
  ]);

  let avgApprovalWaitDays = 0;
  if (approvedAgg.length > 0) {
    const totalMs = approvedAgg.reduce((sum, s) => {
      if (!s.reviewedAt) return sum;
      return sum + (s.reviewedAt.getTime() - s.createdAt.getTime());
    }, 0);
    avgApprovalWaitDays =
      Math.round((totalMs / approvedAgg.length / 86_400_000) * 10) / 10;
  }

  let avgPerUser = 0;
  if (totalSubmittersGroup.length > 0) {
    const totalSubs = totalSubmittersGroup.reduce(
      (sum, g) => sum + g._count._all,
      0,
    );
    avgPerUser =
      Math.round((totalSubs / totalSubmittersGroup.length) * 10) / 10;
  }

  return {
    current,
    weeklyAdded,
    monthlyAdded,
    history: labels.map((label, i) => ({ label, count: values[i] })),
    submissions: { inVote, inReview },
    mySubmissions: {
      active: mineActive,
      inVote: mineInVote,
      inReview: mineInReview,
    },
    avgPerUser,
    avgApprovalWaitDays,
  };
});
