import { randomUUID } from "node:crypto";
import https from "node:https";

class OpenAI_Conversation
{
	messages = [];
	ident;

	constructor(apiKey, systemPrompt, model = "gpt-4o-mini") {

		this.options = {
			hostname: "api.openai.com",
			port: 443,
			path: "/v1/chat/completions",
			method: "POST",
			headers: {
				"Content-Type": "application/json",
				"Authorization": `Bearer ${apiKey}`
			}
		};

		this.payload = {
			model: model,
			messages: [
				{ role: "system", content: systemPrompt }
			],
			stream: true,
		};

		this.ident = randomUUID();
	}

	async sendPrompt(prompt, onStream) {
  this.payload.messages.push({ role: "user", content: prompt });

  const payloadString = JSON.stringify(this.payload);
  this.options.headers["Content-Length"] = Buffer.byteLength(payloadString);

  return new Promise((resolve, reject) => {
    const req = https.request(this.options, (res) => {
      res.setEncoding("utf8");

      let assistantReply = "";
      let buffer = ""; // accumulates incomplete chunks

      res.on("data", (chunk) => {
        buffer += chunk; // append new chunk to buffer
        const lines = buffer.split("\n");

        // keep last partial line in buffer (not processed yet)
        buffer = lines.pop();

        for (const line of lines) {
          if (!line.startsWith("data: ")) continue;

          const message = line.replace(/^data: /, "");
          if (message === "[DONE]") return;

          try {
            const parsed = JSON.parse(message);
            const content = parsed.choices[0]?.delta?.content || "";
            if (content) {
              assistantReply += content;
              if (onStream) onStream(content);
            }
          } catch (err) {
            // If parse fails here, it's fine, partial JSON goes into `buffer`
          }
        }
      });

      res.on("end", () => {
        if (assistantReply) {
          this.payload.messages.push({ role: "assistant", content: assistantReply });
        }
        resolve(assistantReply);
      });
    });

    req.on("error", (err) => reject(err));

    req.write(payloadString);
    req.end();
  });
	}

}

export default OpenAI_Conversation;