import type { FastifyInstance } from 'fastify';
import type { FastifySchema } from 'fastify';
import type pg from 'pg';
import { requireRole, type Authenticate } from '../../../shared/auth.js';
import { errorSchema } from '../../../shared/swagger.js';

interface AdminStatsDeps {
  pool: pg.Pool;
  authenticate: Authenticate;
}

const statsSchema: FastifySchema = {
  tags: ['Admin'],
  summary: 'Admin dashboard stats',
  description: 'KPIs del dashboard: pedidos hoy, ingresos, productos sin stock, etc.',
  response: { 401: errorSchema, 403: errorSchema },
};

export async function registerAdminStatsRoutes(
  app: FastifyInstance,
  deps: AdminStatsDeps,
): Promise<void> {
  app.get('/admin/stats', { schema: statsSchema }, async (request, reply) => {
    const user = await deps.authenticate(request);
    requireRole(user, 'admin');

    const pool = deps.pool;

    // All queries run in parallel for speed
    const [
      ordersToday,
      revenueToday,
      ordersByState,
      outOfStockVariants,
      totalProducts,
      newCustomersThisMonth,
    ] = await Promise.all([
      // Orders today
      pool
        .query<{ count: string }>(
          `SELECT COUNT(*)::text AS count FROM orders_orders
           WHERE created_at >= CURRENT_DATE`,
        )
        .then((r) => parseInt(r.rows[0]?.count ?? '0', 10)),

      // Revenue today (sum of PAID, PROCESSING, SHIPPED, DELIVERED orders)
      pool
        .query<{ total: string }>(
          `SELECT COALESCE(SUM(total_cents), 0)::text AS total FROM orders_orders
           WHERE created_at >= CURRENT_DATE
             AND state IN ('PAID','PROCESSING','SHIPPED','DELIVERED')`,
        )
        .then((r) => parseInt(r.rows[0]?.total ?? '0', 10)),

      // Orders by state
      pool
        .query<{ state: string; count: string }>(
          `SELECT state, COUNT(*)::text AS count FROM orders_orders
           GROUP BY state ORDER BY count DESC`,
        )
        .then((r) => Object.fromEntries(r.rows.map((row) => [row.state, parseInt(row.count, 10)]))),

      // Out-of-stock variants
      pool
        .query<{ count: string }>(
          `SELECT COUNT(*)::text AS count
           FROM inventory_stock s
           WHERE s.available <= 0`,
        )
        .then((r) => parseInt(r.rows[0]?.count ?? '0', 10)),

      // Total active products
      pool
        .query<{ count: string }>(
          `SELECT COUNT(*)::text AS count FROM catalog_products WHERE state = 'active'`,
        )
        .then((r) => parseInt(r.rows[0]?.count ?? '0', 10)),

      // New customers this month
      pool
        .query<{ count: string }>(
          `SELECT COUNT(*)::text AS count FROM identity_users
           WHERE role = 'customer'
             AND created_at >= DATE_TRUNC('month', CURRENT_DATE)`,
        )
        .then((r) => parseInt(r.rows[0]?.count ?? '0', 10)),
    ]);

    return reply.send({
      ordersToday,
      revenueTodayCents: revenueToday,
      revenueTodayFormatted: `€${(revenueToday / 100).toFixed(2)}`,
      ordersByState,
      outOfStockVariants,
      totalActiveProducts: totalProducts,
      newCustomersThisMonth,
      generatedAt: new Date().toISOString(),
    });
  });
}
