import { prisma } from "../../lib/db";
import { makeResponse } from "../../lib/response";
import { ERROR_MESSAGES } from "../../lib/errors";
import { computePreviewCostUsd, hourlyRateUsd } from "../../lib/cost";
import { PreviewStatus } from "@prisma/client";

function requireAuth(ctr: any) {
  const auth = ctr.getAuth?.();
  if (!auth?.success) return null;
  return auth.user;
}

const ACTIVE_STATUSES: PreviewStatus[] = ["PROVISIONING", "BUILDING", "RUNNING"];

// Instance-wide ("global") stats for the Overview homepage.
export async function getStats(ctr: any) {
  const user = requireAuth(ctr);
  if (!user) return makeResponse({ ctr, content: { code: 401, message: ERROR_MESSAGES.UNAUTHORIZED.message } });

  const [
    totalUsers,
    totalRepos,
    enabledRepos,
    totalPreviews,
    activePreviews,
    activeInstances,
    byStatusRaw,
    recentRaw,
    costRaw,
  ] = await Promise.all([
    prisma.user.count(),
    prisma.repoConfig.count(),
    prisma.repoConfig.count({ where: { isEnabled: true } }),
    prisma.preview.count(),
    prisma.preview.count({ where: { status: { in: ACTIVE_STATUSES } } }),
    // A live EC2 instance is any preview still holding an instanceId.
    prisma.preview.count({ where: { instanceId: { not: null } } }),
    prisma.preview.groupBy({ by: ["status"], _count: { _all: true } }),
    prisma.preview.findMany({
      orderBy: { updatedAt: "desc" },
      take: 8,
      include: { repoConfig: { select: { repoOwner: true, repoName: true } } },
    }),
    prisma.preview.findMany({
      select: { accumulatedCostUsd: true, instanceLaunchedAt: true, instanceType: true },
    }),
  ]);

  const byStatus: Record<string, number> = {};
  for (const row of byStatusRaw) byStatus[row.status] = row._count._all;

  // Instance-wide (this PP deployment) estimated EC2 spend, and the current
  // hourly burn rate across every live instance. See lib/cost.ts.
  const now = new Date();
  let totalCostUsd = 0;
  let hourlyBurnUsd = 0;
  for (const p of costRaw) {
    totalCostUsd += computePreviewCostUsd(p, now);
    if (p.instanceLaunchedAt) hourlyBurnUsd += hourlyRateUsd(p.instanceType);
  }

  return makeResponse({
    ctr,
    content: {
      code: 200,
      data: {
        totalUsers,
        totalRepos,
        enabledRepos,
        totalPreviews,
        activePreviews,
        activeInstances,
        totalCostUsd,
        hourlyBurnUsd,
        byStatus,
        recentPreviews: recentRaw.map(p => ({
          id: p.id,
          prNumber: p.prNumber,
          prTitle: p.prTitle,
          status: p.status,
          stopReason: p.stopReason,
          instanceIp: p.instanceIp,
          port: p.port,
          updatedAt: p.updatedAt,
          repoOwner: p.repoConfig.repoOwner,
          repoName: p.repoConfig.repoName,
        })),
      },
    },
  });
}
