import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { Prisma } from "@agentlens/database";
import { auth } from "@/auth";

export async function GET(request: NextRequest) {
  try {
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { searchParams } = new URL(request.url);
    const page = parseInt(searchParams.get("page") ?? "1", 10);
    const limit = parseInt(searchParams.get("limit") ?? "20", 10);
    const type = searchParams.get("type");
    const search = searchParams.get("search");
    const sort = searchParams.get("sort") ?? "newest";

    // Validate pagination
    if (isNaN(page) || page < 1) {
      return NextResponse.json(
        { error: "Invalid page parameter. Must be a positive integer." },
        { status: 400 }
      );
    }
    if (isNaN(limit) || limit < 1 || limit > 100) {
      return NextResponse.json(
        { error: "Invalid limit parameter. Must be between 1 and 100." },
        { status: 400 }
      );
    }

    // Validate type
    const validTypes = [
      "TOOL_SELECTION",
      "ROUTING",
      "RETRY",
      "ESCALATION",
      "MEMORY_RETRIEVAL",
      "PLANNING",
      "CUSTOM",
    ];
    if (type && !validTypes.includes(type)) {
      return NextResponse.json(
        { error: `Invalid type. Must be one of: ${validTypes.join(", ")}` },
        { status: 400 }
      );
    }

    // Validate sort
    const validSorts = ["newest", "oldest", "costliest"];
    if (!validSorts.includes(sort)) {
      return NextResponse.json(
        { error: `Invalid sort. Must be one of: ${validSorts.join(", ")}` },
        { status: 400 }
      );
    }

    const where: Prisma.DecisionPointWhereInput = {
      trace: { userId: session.user.id },
    };
    if (type) {
      where.type = type as Prisma.EnumDecisionTypeFilter["equals"];
    }
    if (search) {
      where.reasoning = {
        contains: search,
        mode: "insensitive",
      };
    }

    // Build order by
    let orderBy: Prisma.DecisionPointOrderByWithRelationInput;
    switch (sort) {
      case "oldest":
        orderBy = { timestamp: "asc" };
        break;
      case "costliest":
        orderBy = { costUsd: "desc" };
        break;
      case "newest":
      default:
        orderBy = { timestamp: "desc" };
        break;
    }

    // Count total
    const total = await prisma.decisionPoint.count({ where });

    // Pagination
    const skip = (page - 1) * limit;
    const totalPages = Math.ceil(total / limit);

    // Fetch decisions with parent trace and span
    const decisions = await prisma.decisionPoint.findMany({
      where,
      include: {
        trace: {
          select: {
            id: true,
            name: true,
          },
        },
        span: {
          select: {
            id: true,
            name: true,
          },
        },
      },
      orderBy,
      skip,
      take: limit,
    });

    return NextResponse.json(
      {
        decisions,
        total,
        page,
        limit,
        totalPages,
      },
      { status: 200 }
    );
  } catch (error) {
    console.error("Error listing decisions:", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 }
    );
  }
}
