import { NextRequest } from "next/server";
import ZAI from "z-ai-web-dev-sdk";

const SYSTEM_PROMPT = `You are Echo, a concise, helpful voice assistant. Follow these rules strictly:

1. **Verbal response**: Reply in ≤ 2 short sentences so it sounds natural when spoken aloud. Be direct and conversational.
2. **Local commands** (optional): If the user's request can be fulfilled by a local OS action, include a single JSON block at the very end of your response using this exact format:

\`\`\`json
{"action": "<command_name>", "params": {"key": "value"}}
\`\`\`

3. Do NOT include the JSON block in your spoken text.
4. Never use markdown formatting, bullet points, or headers in the spoken text.
5. If the user asks you to do something you cannot do, be honest about it briefly.`;

// Store conversation history per session
const sessionHistories = new Map<string, Array<{ role: string; content: string }>>();

export async function POST(request: NextRequest) {
  try {
    const { message, conversationId } = await request.json();

    if (!message) {
      return new Response(JSON.stringify({ error: "Message is required" }), {
        status: 400,
        headers: { "Content-Type": "application/json" },
      });
    }

    // Get or create session history
    const history = sessionHistories.get(conversationId) || [];
    history.push({ role: "user", content: message });

    // Keep last 20 messages for context
    const recentHistory = history.slice(-20);

    const zai = await ZAI.create();

    // Use streaming for real-time token delivery
    const stream = await zai.chat.completions.create({
      messages: [
        { role: "system", content: SYSTEM_PROMPT },
        ...recentHistory,
      ],
      temperature: 0.7,
      max_tokens: 300,
      stream: true,
    });

    // Create a ReadableStream for SSE
    const encoder = new TextEncoder();
    const readable = new ReadableStream({
      async start(controller) {
        let fullText = "";

        try {
          // Process the stream
          if (stream && typeof stream === "object" && "choices" in stream) {
            // Non-streaming fallback
            const nonStream = stream as { choices: Array<{ message?: { content?: string } }> };
            const content = nonStream.choices[0]?.message?.content || "";
            fullText = content;
            const cleaned = content
              .replace(/<think[^>]*>.*?<\/think\s*>/gs, "")
              .replace(/```json.*?```/gs, "")
              .trim();
            controller.enqueue(
              encoder.encode(`data: ${JSON.stringify({ token: cleaned, done: false })}\n\n`)
            );
            controller.enqueue(
              encoder.encode(`data: ${JSON.stringify({ token: "", done: true, fullText: cleaned })}\n\n`)
            );
          } else if (Symbol.asyncIterator in Object(stream)) {
            // Streaming response
            for await (const chunk of stream as AsyncIterable<any>) {
              const delta = chunk.choices?.[0]?.delta?.content;
              if (delta) {
                fullText += delta;
                controller.enqueue(
                  encoder.encode(`data: ${JSON.stringify({ token: delta, done: false })}\n\n`)
                );
              }
            }
            // Send final message
            const cleaned = fullText
              .replace(/<think[^>]*>.*?<\/think\s*>/gs, "")
              .replace(/```json.*?```/gs, "")
              .trim();
            controller.enqueue(
              encoder.encode(`data: ${JSON.stringify({ token: "", done: true, fullText: cleaned })}\n\n`)
            );
          }

          // Store in history
          const cleanedForHistory = fullText
            .replace(/<think[^>]*>.*?<\/think\s*>/gs, "")
            .replace(/```json.*?```/gs, "")
            .trim();
          history.push({ role: "assistant", content: cleanedForHistory });
          sessionHistories.set(conversationId, history);
        } catch (error) {
          console.error("Stream error:", error);
          controller.enqueue(
            encoder.encode(
              `data: ${JSON.stringify({ token: "", done: true, error: true, fullText: "I'm sorry, something went wrong." })}\n\n`
            )
          );
        } finally {
          controller.enqueue(encoder.encode("data: [DONE]\n\n"));
          controller.close();
        }
      },
    });

    return new Response(readable, {
      headers: {
        "Content-Type": "text/event-stream",
        "Cache-Control": "no-cache",
        Connection: "keep-alive",
      },
    });
  } catch (error) {
    console.error("Chat stream API error:", error);
    return new Response(
      JSON.stringify({
        message: "Sorry, I had trouble thinking about that.",
        error: true,
      }),
      {
        status: 200,
        headers: { "Content-Type": "application/json" },
      }
    );
  }
}
