import { NextRequest, NextResponse } from 'next/server';
import { getSession } from '@/lib/auth';
import { db, schema } from '@/lib/db';
import { eq, desc } from 'drizzle-orm';
import { calculateCompanyInvoice } from '@/lib/billing-service';
import { getCompanyById } from '@/lib/companies';
import { getPlanCapabilities } from '@/lib/plan-access';
import { grossEurCentsFromTokens } from '@/lib/conversion-pricing';

/**
 * GET /api/billing/invoice
 * Returns the current month's invoice for the caller's company: one line item
 * per translated conversion, the running total, and recent past invoices.
 * Owner or admin only.
 */
export async function GET(request: NextRequest) {
  const session = await getSession(request.cookies.get('scriba.access_token')?.value);
  if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });

  const me = await db.query.users.findFirst({
    where: eq(schema.users.id, session.user.id),
    columns: { role: true, companyId: true, isOwner: true },
  });
  if (!me?.companyId) {
    return NextResponse.json({ error: 'You must belong to a company to view invoices' }, { status: 403 });
  }
  if (!me.isOwner && me.role !== 'admin') {
    return NextResponse.json({ error: 'Only the company owner can view invoices' }, { status: 403 });
  }

  const company = await getCompanyById(me.companyId);
  if (!company) return NextResponse.json({ error: 'Company not found' }, { status: 404 });

  const now = new Date();
  const periodStart = new Date(now.getFullYear(), now.getMonth(), 1);
  const periodEnd = new Date(now.getFullYear(), now.getMonth() + 1, 1);

  const invoice = await calculateCompanyInvoice(me.companyId, periodStart, periodEnd);

  // Annual license credit (single source of truth shared with the Credits page).
  const allowanceTokens = getPlanCapabilities(company.package).includedCreditsTokens;
  const remainingTokens = typeof company.licenseCreditsRemaining === 'number'
    ? company.licenseCreditsRemaining
    : allowanceTokens;
  const allowanceCents = grossEurCentsFromTokens(allowanceTokens);
  const remainingCents = grossEurCentsFromTokens(Math.max(0, remainingTokens));
  const credits = {
    allowanceCents,
    remainingCents,
    usedCents: Math.max(0, allowanceCents - remainingCents),
  };

  const owner = await db.query.users.findFirst({
    where: eq(schema.users.id, company.ownerId),
    columns: { id: true, email: true, name: true },
  });

  const records = await db.query.billingRecords.findMany({
    where: eq(schema.billingRecords.userId, company.ownerId),
    orderBy: [desc(schema.billingRecords.periodStart)],
    limit: 24,
  });

  return NextResponse.json({
    company: {
      id: company.id,
      name: company.name,
      package: company.package,
      suspended: Boolean(company.suspendedAt),
      suspensionReason: company.suspendedReason ?? null,
      financialData: company.financialData ?? {},
      owner: owner ? { email: owner.email, name: owner.name } : null,
    },
    period: {
      start: periodStart.toISOString(),
      end: periodEnd.toISOString(),
      // Charge happens on the 1st of next month for the current period.
      chargeDate: periodEnd.toISOString(),
    },
    credits,
    invoice,
    records,
  });
}
