import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { logger } from "@/lib/logger";

/**
 * Escape a value for CSV output.
 * Wraps in double-quotes if the value contains commas, double-quotes, or newlines.
 * Doubles any internal double-quotes per RFC 4180.
 */
function csvEscape(value: string): string {
  if (value.includes(",") || value.includes('"') || value.includes("\n") || value.includes("\r")) {
    return `"${value.replace(/"/g, '""')}"`;
  }
  return value;
}

/**
 * GET /api/token/conversations/:id/export?format=json|csv
 *
 * Export a Token conversation as a downloadable JSON or CSV file.
 *
 * Auth: NextAuth session required.
 * Ownership: userId must match the conversation owner.
 * Query params:
 *   - format: "json" (default) or "csv"
 */
export async function GET(
  req: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  const session = await auth();
  if (!session?.user?.id) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { id } = await params;
  const { searchParams } = new URL(req.url);
  const format = searchParams.get("format") ?? "json";

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

  try {
    const conversation = await db.tokenConversation.findFirst({
      where: { id, userId: session.user.id },
      select: {
        id: true,
        title: true,
        createdAt: true,
        updatedAt: true,
        messages: {
          orderBy: { createdAt: "asc" },
          select: {
            id: true,
            role: true,
            content: true,
            model: true,
            costUsd: true,
            latencyMs: true,
            inputTokens: true,
            outputTokens: true,
            messageType: true,
            createdAt: true,
          },
        },
      },
    });

    if (!conversation) {
      return NextResponse.json({ error: "Conversation not found" }, { status: 404 });
    }

    const safeTitle = conversation.title.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 50);
    const timestamp = new Date().toISOString().slice(0, 10);

    logger.info(
      {
        action: "token_conversation_exported",
        conversation_id: id,
        format,
        message_count: conversation.messages.length,
      },
      "Token conversation exported",
    );

    if (format === "csv") {
      const headers = ["role", "content", "model", "costUsd", "latencyMs", "createdAt"];
      const rows = conversation.messages.map((msg) => [
        csvEscape(msg.role),
        csvEscape(msg.content),
        csvEscape(msg.model ?? ""),
        String(msg.costUsd ?? 0),
        String(msg.latencyMs ?? 0),
        csvEscape(msg.createdAt instanceof Date ? msg.createdAt.toISOString() : String(msg.createdAt)),
      ]);

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

      return new NextResponse(csv, {
        status: 200,
        headers: {
          "Content-Type": "text/csv; charset=utf-8",
          "Content-Disposition": `attachment; filename="token-${safeTitle}-${timestamp}.csv"`,
        },
      });
    }

    // JSON format
    const payload = {
      exportedAt: new Date().toISOString(),
      conversation: {
        id: conversation.id,
        title: conversation.title,
        createdAt: conversation.createdAt,
        updatedAt: conversation.updatedAt,
        messageCount: conversation.messages.length,
        messages: conversation.messages,
      },
    };

    const jsonStr = JSON.stringify(payload, null, 2);

    return new NextResponse(jsonStr, {
      status: 200,
      headers: {
        "Content-Type": "application/json; charset=utf-8",
        "Content-Disposition": `attachment; filename="token-${safeTitle}-${timestamp}.json"`,
      },
    });
  } catch (err) {
    logger.error(
      { err, action: "token_conversation_export_error", conversation_id: id, format },
      "Failed to export conversation",
    );
    return NextResponse.json(
      { error: "Failed to export conversation" },
      { status: 500 },
    );
  }
}
