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

export const dynamic = "force-dynamic";

interface TraceUpdateData {
  type: "new" | "updated";
  trace: {
    id: string;
    name: string;
    status: "RUNNING" | "COMPLETED" | "ERROR";
    startedAt: string;
    endedAt: string | null;
    totalDuration: number | null;
    tags: string[];
    metadata: Record<string, unknown> | null;
    totalCost: number | null;
    totalTokens: number | null;
    createdAt: string;
    updatedAt: string;
  };
}

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

  const currentUserId = session.user.id;

  const headers = new Headers();
  headers.set("Content-Type", "text/event-stream");
  headers.set("Cache-Control", "no-cache");
  headers.set("Connection", "keep-alive");

  const encoder = new TextEncoder();
  let lastCheck = new Date();
  let heartbeatInterval: NodeJS.Timeout | null = null;
  let pollInterval: NodeJS.Timeout | null = null;

  const stream = new ReadableStream({
    async start(controller) {
      const sendSSE = (event: string, data: unknown) => {
        const message = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
        controller.enqueue(encoder.encode(message));
      };

      const pollForUpdates = async () => {
        try {
          const newTraces = await prisma.trace.findMany({
            where: {
              userId: currentUserId,
              OR: [
                { createdAt: { gt: lastCheck } },
                { updatedAt: { gt: lastCheck } },
              ],
            },
            select: {
              id: true,
              name: true,
              status: true,
              startedAt: true,
              endedAt: true,
              totalDuration: true,
              tags: true,
              metadata: true,
              totalCost: true,
              totalTokens: true,
              createdAt: true,
              updatedAt: true,
            },
          });

          for (const trace of newTraces) {
            const type = trace.createdAt > lastCheck ? "new" : "updated";
            sendSSE("trace-update", {
              type,
              trace: {
                ...trace,
                startedAt: trace.startedAt.toISOString(),
                endedAt: trace.endedAt?.toISOString() ?? null,
                createdAt: trace.createdAt.toISOString(),
                updatedAt: trace.updatedAt.toISOString(),
              },
            });
          }

          lastCheck = new Date();
        } catch (error) {
          console.error("Error polling for trace updates:", error);
        }
      };

      const sendHeartbeat = () => {
        sendSSE("heartbeat", { timestamp: new Date().toISOString() });
      };

      // Send initial heartbeat
      sendHeartbeat();

      // Poll every 2 seconds for updates
      pollInterval = setInterval(pollForUpdates, 2000);

      // Send heartbeat every 15 seconds
      heartbeatInterval = setInterval(sendHeartbeat, 15000);

      // Cleanup function
      request.signal.addEventListener("abort", () => {
        if (pollInterval) clearInterval(pollInterval);
        if (heartbeatInterval) clearInterval(heartbeatInterval);
        controller.close();
      });
    },
  });

  return new Response(stream, { headers });
}
