/**
 * GET /api/analytics/revenue — Revenue analytics for admin dashboard.
 *
 * Queries subscriptions and payments containers to compute:
 * MRR, ARR, churn rate, LTV, ARPU, and monthly revenue breakdown.
 */

import { NextRequest, NextResponse } from 'next/server';
import { getCurrentUserFromRequest } from '@/lib/auth-server';
import { getCollection } from '@/lib/datastore';
import { getRequestProductId } from '@/lib/product-config';

interface MonthlyRevenue {
  month: string; // YYYY-MM
  revenue: number;
  subscriptions: number;
}

interface RevenueResponse {
  mrr: number;
  arr: number;
  mrrChange: number; // percentage vs prior month
  totalRevenue: number;
  revenueByMonth: MonthlyRevenue[];
  churnRate: number;
  churnCount: number;
  ltv: number;
  arpu: number;
  newSubscriptions: number;
  canceledSubscriptions: number;
}

export async function GET(req: NextRequest) {
  try {
    const caller = await getCurrentUserFromRequest(req);
    if (!caller) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const url = new URL(req.url);
    const months = parseInt(url.searchParams.get('months') ?? '6', 10);
    const productId = getRequestProductId(req);

    const now = new Date();
    const sinceDate = new Date(now.getFullYear(), now.getMonth() - months, 1).toISOString();

    // ---- Active subscriptions for MRR ----
    const subsCollection = getCollection('subscriptions', '/userId');
    const activeSubs = await subsCollection.rawQuery<{
      id: string;
      plan: string;
      price: number;
      status: string;
      createdAt: string;
    }>(
      'SELECT c.id, c.plan, c.price, c.status, c.createdAt FROM c ' +
        "WHERE c.productId = @pid AND c.status = 'active'",
      { pid: productId }
    );

    // ---- Canceled subscriptions (last N months) ----
    const canceledSubs = await subsCollection.rawQuery<{ id: string; canceledAt: string }>(
      'SELECT c.id, c.canceledAt FROM c ' +
        "WHERE c.productId = @pid AND c.status = 'canceled' " +
        'AND c.canceledAt >= @since',
      { pid: productId, since: sinceDate }
    );

    // ---- New subscriptions (last N months) ----
    const newSubs = await subsCollection.rawQuery<{ id: string; createdAt: string }>(
      'SELECT c.id, c.createdAt FROM c WHERE c.productId = @pid AND c.createdAt >= @since',
      { pid: productId, since: sinceDate }
    );

    // ---- Payments (last N months) ----
    const paymentsCollection = getCollection('payments', '/userId');
    const payments = await paymentsCollection.rawQuery<{ amount: number; paidAt: string }>(
      'SELECT c.amount, c.paidAt FROM c ' +
        "WHERE c.productId = @pid AND c.status = 'succeeded' " +
        'AND c.paidAt >= @since',
      { pid: productId, since: sinceDate }
    );

    // ---- Compute metrics ----
    const mrr = activeSubs.reduce((sum, s) => sum + (s.price ?? 0), 0);
    const arr = mrr * 12;

    const totalRevenue = payments.reduce((sum, p) => sum + (p.amount ?? 0), 0);

    // Revenue by month
    const monthBuckets: Record<string, { revenue: number; subscriptions: number }> = {};
    for (let i = 0; i < months; i++) {
      const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
      const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
      monthBuckets[key] = { revenue: 0, subscriptions: 0 };
    }

    for (const p of payments) {
      const key = (p.paidAt ?? '').slice(0, 7);
      if (monthBuckets[key]) {
        monthBuckets[key].revenue += p.amount ?? 0;
      }
    }

    for (const s of newSubs) {
      const key = (s.createdAt ?? '').slice(0, 7);
      if (monthBuckets[key]) {
        monthBuckets[key].subscriptions += 1;
      }
    }

    const revenueByMonth: MonthlyRevenue[] = Object.entries(monthBuckets)
      .sort(([a], [b]) => a.localeCompare(b))
      .map(([month, data]) => ({ month, ...data }));

    // MRR change vs prior month
    const currentMonth = revenueByMonth[revenueByMonth.length - 1];
    const priorMonth = revenueByMonth[revenueByMonth.length - 2];
    const mrrChange =
      priorMonth && priorMonth.revenue > 0
        ? ((currentMonth.revenue - priorMonth.revenue) / priorMonth.revenue) * 100
        : 0;

    // Churn
    const totalSubsStart = activeSubs.length + canceledSubs.length;
    const churnRate = totalSubsStart > 0 ? (canceledSubs.length / totalSubsStart) * 100 : 0;

    // LTV & ARPU
    const activeCount = activeSubs.length || 1;
    const arpu = mrr / activeCount;
    const monthlyChurn = churnRate / 100 || 0.01; // avoid division by zero
    const ltv = arpu / monthlyChurn;

    const response: RevenueResponse = {
      mrr: Math.round(mrr * 100) / 100,
      arr: Math.round(arr * 100) / 100,
      mrrChange: Math.round(mrrChange * 10) / 10,
      totalRevenue: Math.round(totalRevenue * 100) / 100,
      revenueByMonth,
      churnRate: Math.round(churnRate * 10) / 10,
      churnCount: canceledSubs.length,
      ltv: Math.round(ltv * 100) / 100,
      arpu: Math.round(arpu * 100) / 100,
      newSubscriptions: newSubs.length,
      canceledSubscriptions: canceledSubs.length,
    };

    return NextResponse.json(response);
  } catch (err) {
    const message = err instanceof Error ? err.message : 'Unknown error';
    return NextResponse.json(
      { error: 'Failed to compute revenue analytics', detail: message },
      { status: 500 }
    );
  }
}
