import { NextRequest, NextResponse } from 'next/server';
import {
  getSupabaseAdmin,
  generateLicenceKey,
  hashKey,
  nextMonthReset,
} from '@/lib/supabase';
import { stripe } from '@/lib/stripe';
import { checkAdminLimit, checkAuth, getClientIp } from '@/lib/admin-auth';

type LicenceRow = {
  id: string;
  email: string;
  plan: string;
  quota_month: number;
  usage_month: number;
  reset_at: string;
  active: boolean;
  flagged: boolean;
  created_at: string;
  stripe_customer_id: string | null;
  stripe_subscription_id: string | null;
};

export async function GET(req: NextRequest) {
  const ip = getClientIp(req);
  if (!checkAdminLimit(ip)) return NextResponse.json({ error: 'rate_limit' }, { status: 429 });
  if (!checkAuth(req)) return NextResponse.json({ error: 'unauthorized' }, { status: 401 });

  const { data, error } = await getSupabaseAdmin()
    .from('licences')
    .select('id, email, plan, quota_month, usage_month, reset_at, active, flagged, created_at, stripe_customer_id, stripe_subscription_id')
    .order('created_at', { ascending: false });

  if (error) return NextResponse.json({ error: 'db_error' }, { status: 500 });

  const licences = (data ?? []) as LicenceRow[];

  // Fetch all Stripe subscriptions in one call and match by ID
  type StripeInfo = { next_payment: number; amount_cents: number; currency: string; status: string };
  const stripeMap: Record<string, StripeInfo> = {};
  let mrr = 0;

  const hasStripe = licences.some(l => l.stripe_subscription_id);
  if (hasStripe) {
    try {
      const subs = await stripe.subscriptions.list({ limit: 100, status: 'all' });
      for (const sub of subs.data) {
        const amount = sub.items.data[0]?.price?.unit_amount ?? 0;
        stripeMap[sub.id] = {
          next_payment: sub.items.data[0]?.current_period_end ?? 0,
          amount_cents: amount,
          currency:     sub.items.data[0]?.price?.currency ?? 'eur',
          status:       sub.status,
        };
        if (sub.status === 'active') mrr += amount / 100;
      }
    } catch {
      // Stripe not configured or API error — degrade gracefully
    }
  }

  const enriched = licences.map(l => ({
    ...l,
    stripe_info: l.stripe_subscription_id
      ? (stripeMap[l.stripe_subscription_id] ?? null)
      : null,
  }));

  return NextResponse.json({ licences: enriched, mrr: Math.round(mrr * 100) / 100 });
}

const PLAN_QUOTAS: Record<string, number> = {
  trial:     10,
  gift:      20,
  starter:   50,
  essentiel: 200,
  pro:       500,
  agency:    999999,
};

export async function POST(req: NextRequest) {
  const ip = getClientIp(req);
  if (!checkAdminLimit(ip)) return NextResponse.json({ error: 'rate_limit' }, { status: 429 });
  if (!checkAuth(req)) return NextResponse.json({ error: 'unauthorized' }, { status: 401 });

  const body = await req.json().catch(() => null);
  if (!body || typeof body !== 'object') {
    return NextResponse.json({ error: 'invalid_json' }, { status: 400 });
  }

  const { email, plan, quota_month } = body as { email?: unknown; plan?: unknown; quota_month?: unknown };

  if (
    !email || typeof email !== 'string' ||
    !/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email) ||
    email.length > 320
  ) {
    return NextResponse.json({ error: 'invalid_email' }, { status: 400 });
  }

  if (!plan || typeof plan !== 'string' || !(plan in PLAN_QUOTAS)) {
    return NextResponse.json({ error: 'invalid_plan' }, { status: 400 });
  }

  const quota = Number(quota_month);
  if (!Number.isInteger(quota) || quota < 1 || quota > 999999) {
    return NextResponse.json({ error: 'invalid_quota' }, { status: 400 });
  }

  const noExpiry = plan === 'trial' || plan === 'gift';

  const key     = generateLicenceKey();
  const keyHash = hashKey(key);

  const { error } = await getSupabaseAdmin().from('licences').insert({
    key_hash:    keyHash,
    email:       email.toLowerCase().trim(),
    plan,
    quota_month: quota,
    usage_month: 0,
    reset_at:    noExpiry ? '2099-12-31T00:00:00.000Z' : nextMonthReset(),
    active:      true,
    allowed_ip:  null,
    flagged:     false,
  });

  if (error) return NextResponse.json({ error: 'db_error' }, { status: 500 });
  return NextResponse.json({ key });
}
