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

type RouteParams = { params: Promise<{ id: string }> };

function extractActionLabel(value: unknown): string {
  if (typeof value === "string") return value;
  if (value && typeof value === "object" && !Array.isArray(value)) {
    const obj = value as Record<string, unknown>;
    if (typeof obj.name === "string") return obj.name;
    if (typeof obj.action === "string") return obj.action;
    if (typeof obj.tool === "string") return obj.tool;
    for (const v of Object.values(obj)) {
      if (typeof v === "string") return v;
    }
  }
  return JSON.stringify(value);
}

// GET /api/traces/[id] — Get single trace with all relations
export async function GET(
  _request: NextRequest,
  { params }: RouteParams
) {
  try {
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { id } = await params;

    if (!id || typeof id !== "string") {
      return NextResponse.json({ error: "Invalid trace ID" }, { status: 400 });
    }

    const trace = await prisma.trace.findFirst({
      where: { id, userId: session.user.id },
      include: {
        decisionPoints: {
          orderBy: {
            timestamp: "asc",
          },
        },
        spans: {
          orderBy: {
            startedAt: "asc",
          },
        },
        events: {
          orderBy: {
            timestamp: "asc",
          },
        },
      },
    });

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

    // Transform data to match frontend expectations
    const transformedTrace = {
      ...trace,
      durationMs: trace.totalDuration,
      costUsd: trace.totalCost,
      decisionPoints: trace.decisionPoints.map((dp) => ({
        id: dp.id,
        type: dp.type,
        chosenAction: extractActionLabel(dp.chosen),
        alternatives: dp.alternatives.map((alt) => extractActionLabel(alt)),
        reasoning: dp.reasoning,
        contextSnapshot: dp.contextSnapshot as Record<string, unknown> | null,
        confidence: null, // Not in schema, default to null
        timestamp: dp.timestamp.toISOString(),
        parentSpanId: dp.parentSpanId,
      })),
      spans: trace.spans.map((span) => ({
        id: span.id,
        name: span.name,
        type: span.type,
        status: span.status === "COMPLETED" ? "OK" : span.status === "ERROR" ? "ERROR" : "CANCELLED",
        startedAt: span.startedAt.toISOString(),
        endedAt: span.endedAt?.toISOString() ?? null,
        durationMs: span.durationMs,
        input: span.input,
        output: span.output,
        metadata: (span.metadata as Record<string, unknown>) ?? {},
        parentSpanId: span.parentSpanId,
      })),
      events: trace.events.map((event) => ({
        id: event.id,
        type: event.type,
        name: event.name,
        timestamp: event.timestamp.toISOString(),
        metadata: (event.metadata as Record<string, unknown>) ?? {},
        spanId: event.spanId,
      })),
    };

    return NextResponse.json({ trace: transformedTrace }, { status: 200 });
  } catch (error) {
    console.error("Error retrieving trace:", error);
    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}

// DELETE /api/traces/[id] — Delete a trace and all related data (cascade)
export async function DELETE(
  _request: NextRequest,
  { params }: RouteParams
) {
  try {
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { id } = await params;

    if (!id || typeof id !== "string") {
      return NextResponse.json({ error: "Invalid trace ID" }, { status: 400 });
    }

    const trace = await prisma.trace.findFirst({
      where: { id, userId: session.user.id },
      select: { id: true },
    });

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

    await prisma.trace.delete({
      where: { id },
    });

    return NextResponse.json({ success: true, deleted: id }, { status: 200 });
  } catch (error) {
    console.error("Error deleting trace:", error);
    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}
