import { NextResponse } from "next/server";
import { cookies } from "next/headers";
import { verifyToken } from "@/lib/auth/jwt";
import {
  getUsageByUser,
  getUsageSummary,
} from "@/lib/db/repos/usageRecordsRepo";
import { jsPDF } from "jspdf";
import autoTable from "jspdf-autotable";

export const dynamic = "force-dynamic";

const MAX_EXPORT_RECORDS = 10000;
const PAGE_SIZE = 100;

async function requireAdmin() {
  const cookieStore = await cookies();
  const token = cookieStore.get("auth_token")?.value;
  if (!token) return null;
  const payload = await verifyToken(token);
  if (!payload || payload.role !== "admin") return null;
  return payload;
}

async function getUserIdFromJwt() {
  const cookieStore = await cookies();
  const token = cookieStore.get("auth_token")?.value;
  if (!token) return null;
  const payload = await verifyToken(token);
  return payload?.userId || null;
}

/**
 * Fetch all records for a user up to MAX_EXPORT_RECORDS, paginating through results.
 */
async function fetchAllRecords(userId, { startDate, endDate, model }) {
  const allRecords = [];
  let page = 1;
  const maxPages = Math.ceil(MAX_EXPORT_RECORDS / PAGE_SIZE);

  while (page <= maxPages) {
    const result = await getUsageByUser(userId, {
      startDate,
      endDate,
      model,
      page,
      limit: PAGE_SIZE,
    });

    allRecords.push(...result.records);

    if (allRecords.length >= MAX_EXPORT_RECORDS || page >= result.totalPages) {
      break;
    }
    page++;
  }

  return allRecords.slice(0, MAX_EXPORT_RECORDS);
}

/**
 * Generate CSV string from usage records.
 */
function generateCSV(records) {
  const headers = [
    "Date",
    "Model",
    "Input Tokens",
    "Output Tokens",
    "Total Tokens",
    "Cost",
    "Credit Used",
    "Status",
    "Endpoint",
  ];

  const rows = records.map((r) => [
    r.timestamp,
    r.model,
    r.inputTokens,
    r.outputTokens,
    r.totalTokens,
    r.cost.toFixed(4),
    r.creditUsed.toFixed(4),
    r.status,
    r.endpoint,
  ]);

  const csv = [headers.join(","), ...rows.map((r) => r.join(","))].join("\n");
  return csv;
}

/**
 * Generate PDF ArrayBuffer from usage records and summary.
 */
function generatePDF(records, summary) {
  const doc = new jsPDF();

  // Title
  doc.setFontSize(18);
  doc.text("Usage Report", 14, 22);

  // Summary section
  doc.setFontSize(12);
  doc.text("Summary", 14, 35);
  doc.setFontSize(10);
  doc.text(`Total Requests: ${summary.requestCount}`, 14, 45);
  doc.text(`Total Tokens: ${summary.totalTokens}`, 14, 52);
  doc.text(`Total Cost: $${summary.totalCost.toFixed(4)}`, 14, 59);
  doc.text(
    `Error Rate: ${
      summary.requestCount > 0
        ? ((summary.errorCount / summary.requestCount) * 100).toFixed(1)
        : 0
    }%`,
    14,
    66
  );

  // Table
  const tableData = records.map((r) => [
    r.timestamp.split("T")[0],
    r.model,
    r.inputTokens,
    r.outputTokens,
    `$${r.cost.toFixed(4)}`,
    r.status,
  ]);

  autoTable(doc, {
    startY: 75,
    head: [["Date", "Model", "Input", "Output", "Cost", "Status"]],
    body: tableData,
  });

  return doc.output("arraybuffer");
}

// GET /api/usage/export — Export usage data as CSV or PDF
export async function GET(request) {
  try {
    const { searchParams } = new URL(request.url);
    const format = searchParams.get("format") || "csv";
    const startDate = searchParams.get("startDate") || undefined;
    const endDate = searchParams.get("endDate") || undefined;
    const model = searchParams.get("model") || undefined;

    // Validate format
    if (format !== "csv" && format !== "pdf") {
      return NextResponse.json(
        { error: "Invalid format. Must be 'csv' or 'pdf'." },
        { status: 400 }
      );
    }

    // Auth check — admin can query any user, regular user only their own
    const admin = await requireAdmin();
    let userId;

    if (admin) {
      const requestedUserId = searchParams.get("userId");
      userId = requestedUserId || admin.userId;
    } else {
      userId = await getUserIdFromJwt();
      if (!userId) {
        return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
      }
    }

    // Fetch records and summary
    const records = await fetchAllRecords(userId, {
      startDate,
      endDate,
      model,
    });
    const summary = await getUsageSummary(userId, startDate, endDate);

    if (format === "csv") {
      const csv = generateCSV(records);
      return new NextResponse(csv, {
        status: 200,
        headers: {
          "Content-Type": "text/csv",
          "Content-Disposition": 'attachment; filename="usage-export.csv"',
        },
      });
    }

    // PDF
    const pdfBuffer = generatePDF(records, summary);
    return new NextResponse(pdfBuffer, {
      status: 200,
      headers: {
        "Content-Type": "application/pdf",
        "Content-Disposition": 'attachment; filename="usage-export.pdf"',
      },
    });
  } catch (error) {
    console.error("[usage/export] GET error:", error);
    return NextResponse.json(
      { error: "Failed to export usage data" },
      { status: 500 }
    );
  }
}
