import { http, HttpResponse, delay } from "msw";
import { initialState, initialMessages } from "../../../fixtures/dummy";
import { AgentMessage, State } from "../../../types";

// Mock state updates for SSE simulation
let currentState = { ...initialState };
const EMPTY_CONVERSATION =
  new URL(window.location.href).searchParams.get("emptyConversation") === "1";
const ADD_NEW_MESSAGES =
  new URL(window.location.href).searchParams.get("addNewMessages") === "1";

const messages = EMPTY_CONVERSATION ? [] : [...initialMessages];

// Text encoder for SSE messages
const encoder = new TextEncoder();

// Helper function to create SSE formatted messages
function formatSSE(event, data) {
  return `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
}

export const handlers = [
  // SSE stream endpoint
  http.get("*/stream", async ({ request }) => {
    const url = new URL(request.url);
    const fromIndex = parseInt(url.searchParams.get("from") || "0");

    // Create a readable stream for SSE
    const stream = new ReadableStream({
      async start(controller) {
        // Send initial state update
        controller.enqueue(encoder.encode(formatSSE("state", currentState)));

        // Send any existing messages that are newer than the fromIndex
        const newMessages = messages.filter((msg) => msg.idx >= fromIndex);
        for (const message of newMessages) {
          controller.enqueue(encoder.encode(formatSSE("message", message)));
        }

        // Simulate heartbeats and new messages
        let heartbeatInterval;
        let messageInterval;

        // Send heartbeats every 30 seconds
        heartbeatInterval = setInterval(() => {
          controller.enqueue(
            encoder.encode(
              formatSSE("heartbeat", { timestamp: new Date().toISOString() }),
            ),
          );
        }, 30000);

        // Add new messages if enabled
        if (ADD_NEW_MESSAGES) {
          messageInterval = setInterval(() => {
            const newMessage = {
              type: "agent" as const,
              end_of_turn: false,
              content: "Here's a new message via SSE",
              timestamp: new Date().toISOString(),
              conversation_id: "37s-g6xg",
              usage: {
                input_tokens: 5,
                cache_creation_input_tokens: 250,
                cache_read_input_tokens: 4017,
                output_tokens: 92,
                cost_usd: 0.0035376,
              },
              start_time: new Date(Date.now() - 2000).toISOString(),
              end_time: new Date().toISOString(),
              elapsed: 2075193375,
              turnDuration: 28393844125,
              idx: messages.length,
            };

            // Add to our messages array
            messages.push(newMessage);

            // Update the state
            currentState = {
              ...currentState,
              message_count: messages.length,
            };

            // Send the message and updated state through SSE
            controller.enqueue(
              encoder.encode(formatSSE("message", newMessage)),
            );
            controller.enqueue(
              encoder.encode(formatSSE("state", currentState)),
            );
          }, 2000); // Add a new message every 2 seconds
        }

        // Clean up on connection close
        request.signal.addEventListener("abort", () => {
          clearInterval(heartbeatInterval);
          if (messageInterval) clearInterval(messageInterval);
        });
      },
    });

    return new HttpResponse(stream, {
      headers: {
        "Content-Type": "text/event-stream",
        "Cache-Control": "no-cache",
        Connection: "keep-alive",
      },
    });
  }),

  // State endpoint (non-streaming version for initial state)
  http.get("*/state", () => {
    return HttpResponse.json(currentState);
  }),

  // Messages endpoint
  http.get("*/messages", ({ request }) => {
    const url = new URL(request.url);
    const startIndex = parseInt(url.searchParams.get("start") || "0");

    return HttpResponse.json(messages.slice(startIndex));
  }),

  // Chat endpoint for sending messages
  http.post("*/chat", async ({ request }) => {
    const body = await request.json();

    // Add a user message
    messages.push({
      type: "user" as const,
      end_of_turn: true,
      content:
        typeof body === "object" && body !== null
          ? String(body.message || "")
          : "",
      timestamp: new Date().toISOString(),
      conversation_id: "37s-g6xg",
      idx: messages.length,
    });

    // Update state
    currentState = {
      ...currentState,
      message_count: messages.length,
    };

    return new HttpResponse(null, { status: 204 });
  }),

  // Cancel endpoint
  http.post("*/cancel", () => {
    return new HttpResponse(null, { status: 204 });
  }),
];
