import { Hono } from "hono";
import { eq, isNull, sql } from "drizzle-orm";
import { useDrizzle } from "@/lib/db.js";
import { chargePoint, transaction, idTag, user } from "@/db/schema.js";
import type { HonoEnv } from "@/types/hono.ts";

const app = new Hono<HonoEnv>();

app.get("/", async (c) => {
  const db = useDrizzle();
  const currentUser = c.get("user");
  const isAdmin = currentUser?.role === "admin";

  if (isAdmin) {
    const [
      totalChargePoints,
      onlineChargePoints,
      activeTransactions,
      totalIdTags,
      todayEnergy,
      todayRevenue,
      totalUsers,
      todayTransactions,
    ] = await Promise.all([
      db.select({ count: sql<number>`count(*)::int` }).from(chargePoint),
      db
        .select({ count: sql<number>`count(*)::int` })
        .from(chargePoint)
        .where(
          sql`${chargePoint.transportStatus} = 'online' and ${chargePoint.lastHeartbeatAt} > now() - interval '120 seconds'`,
        ),
      db
        .select({ count: sql<number>`count(*)::int` })
        .from(transaction)
        .where(isNull(transaction.stopTimestamp)),
      db.select({ count: sql<number>`count(*)::int` }).from(idTag),
      db
        .select({
          total: sql<number>`coalesce(sum(${transaction.stopMeterValue} - ${transaction.startMeterValue}), 0)::int`,
        })
        .from(transaction)
        .where(sql`${transaction.stopTimestamp} >= date_trunc('day', now())`),
      db
        .select({ total: sql<number>`coalesce(sum(${transaction.chargeAmount}), 0)::int` })
        .from(transaction)
        .where(sql`${transaction.stopTimestamp} >= date_trunc('day', now())`),
      db.select({ count: sql<number>`count(*)::int` }).from(user),
      db
        .select({ count: sql<number>`count(*)::int` })
        .from(transaction)
        .where(sql`${transaction.stopTimestamp} >= date_trunc('day', now())`),
    ]);

    return c.json({
      totalChargePoints: totalChargePoints[0].count,
      onlineChargePoints: onlineChargePoints[0].count,
      activeTransactions: activeTransactions[0].count,
      totalIdTags: totalIdTags[0].count,
      todayEnergyWh: todayEnergy[0].total,
      todayRevenue: todayRevenue[0].total,
      totalUsers: totalUsers[0].count,
      todayTransactions: todayTransactions[0].count,
    });
  }

  // User-scoped stats
  if (!currentUser) return c.json({ error: "Unauthorized" }, 401);

  const userId = currentUser.id;

  const [userIdTags, totalBalance, activeCount, totalTxCount, todayEnergy, todayTxCount] = await Promise.all([
    // Cards belonging to this user
    db
      .select({ count: sql<number>`count(*)::int` })
      .from(idTag)
      .where(eq(idTag.userId, userId)),
    // Sum of balances
    db
      .select({ total: sql<number>`coalesce(sum(${idTag.balance}), 0)::int` })
      .from(idTag)
      .where(eq(idTag.userId, userId)),
    // Active transactions for user's cards
    db
      .select({ count: sql<number>`count(*)::int` })
      .from(transaction)
      .innerJoin(idTag, eq(transaction.idTag, idTag.idTag))
      .where(sql`${isNull(transaction.stopTimestamp)} and ${idTag.userId} = ${userId}`),
    // Total transactions for user's cards
    db
      .select({ count: sql<number>`count(*)::int` })
      .from(transaction)
      .innerJoin(idTag, eq(transaction.idTag, idTag.idTag))
      .where(eq(idTag.userId, userId)),
    // Today's energy for user's cards
    db
      .select({
        total: sql<number>`coalesce(sum(${transaction.stopMeterValue} - ${transaction.startMeterValue}), 0)::int`,
      })
      .from(transaction)
      .innerJoin(idTag, eq(transaction.idTag, idTag.idTag))
      .where(
        sql`${transaction.stopTimestamp} >= date_trunc('day', now()) and ${idTag.userId} = ${userId}`,
      ),
    // Today's completed transactions for user's cards
    db
      .select({ count: sql<number>`count(*)::int` })
      .from(transaction)
      .innerJoin(idTag, eq(transaction.idTag, idTag.idTag))
      .where(
        sql`${transaction.stopTimestamp} >= date_trunc('day', now()) and ${idTag.userId} = ${userId}`,
      ),
  ]);

  return c.json({
    totalIdTags: userIdTags[0].count,
    totalBalance: totalBalance[0].total,
    activeTransactions: activeCount[0].count,
    totalTransactions: totalTxCount[0].count,
    todayEnergyWh: todayEnergy[0].total,
    todayTransactions: todayTxCount[0].count,
  });
});

export default app;
