import { DEFAULT_BASE_URL, DEFAULT_MODEL, DEFAULT_SYSTEM_PROMPT } from "../../shared/settings.js";
import { parseAnalyzePayload } from "../../shared/schema.js";
import { buildUserPrompt } from "../prompt-builder.js";
import { getStoredSettings } from "./settings-store.js";

export async function analyzeRequest(payload) {
  const parsedPayload = parseAnalyzePayload(payload);
  const settings = await getStoredSettings();
  if (!settings.openaiApiKey) {
    throw new Error("Missing OpenAI API key. Open settings and save your API key first.");
  }

  const model = settings.openaiModel || DEFAULT_MODEL;
  const baseUrl = settings.openaiBaseUrl || DEFAULT_BASE_URL;
  const systemPrompt = settings.systemPrompt || DEFAULT_SYSTEM_PROMPT;

  const userContent = [
    {
      type: "input_text",
      text: buildUserPrompt(parsedPayload)
    }
  ];

  if (parsedPayload.includeScreenshot && parsedPayload.screenshotDataUrl) {
    userContent.push({
      type: "input_image",
      image_url: parsedPayload.screenshotDataUrl
    });
  }

  const response = await fetch(`${baseUrl}/responses`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${settings.openaiApiKey}`
    },
    body: JSON.stringify({
      model,
      input: [
        {
          role: "system",
          content: [{ type: "input_text", text: systemPrompt }]
        },
        {
          role: "user",
          content: userContent
        }
      ]
    })
  });

  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`OpenAI API error (${response.status}): ${errorText}`);
  }

  const data = await response.json();
  const text = extractTextFromResponse(data);
  if (!text) {
    throw new Error("The model response was empty.");
  }

  return {
    text,
    usage: data.usage || null,
    model: data.model || model
  };
}

export async function analyzeRequestStream(payload, handlers) {
  const parsedPayload = parseAnalyzePayload(payload);
  const settings = await getStoredSettings();
  if (!settings.openaiApiKey) {
    throw new Error("Missing OpenAI API key. Open settings and save your API key first.");
  }

  const model = settings.openaiModel || DEFAULT_MODEL;
  const baseUrl = settings.openaiBaseUrl || DEFAULT_BASE_URL;
  const systemPrompt = settings.systemPrompt || DEFAULT_SYSTEM_PROMPT;

  const userContent = [
    {
      type: "input_text",
      text: buildUserPrompt(parsedPayload)
    }
  ];

  if (parsedPayload.includeScreenshot && parsedPayload.screenshotDataUrl) {
    userContent.push({
      type: "input_image",
      image_url: parsedPayload.screenshotDataUrl
    });
  }

  const response = await fetch(`${baseUrl}/responses`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${settings.openaiApiKey}`
    },
    signal: handlers?.signal,
    body: JSON.stringify({
      model,
      stream: true,
      input: [
        {
          role: "system",
          content: [{ type: "input_text", text: systemPrompt }]
        },
        {
          role: "user",
          content: userContent
        }
      ]
    })
  });

  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`OpenAI API error (${response.status}): ${errorText}`);
  }

  if (!response.body) {
    throw new Error("模型流式响应不可用。");
  }

  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let buffer = "";
  let finalResult = {
    text: "",
    usage: null,
    model
  };

  while (true) {
    const { done, value } = await reader.read();
    buffer += decoder.decode(value || new Uint8Array(), { stream: !done });
    const chunks = buffer.split(/\n\n/);
    buffer = chunks.pop() || "";

    for (const chunk of chunks) {
      const event = parseSseEvent(chunk);
      if (!event) {
        continue;
      }
      if (event === "[DONE]") {
        continue;
      }

      const delta = extractStreamDelta(event);
      if (delta) {
        finalResult.text += delta;
        handlers?.onDelta?.(delta);
      }

      if (event.type === "response.completed") {
        finalResult = {
          text: finalResult.text || extractTextFromResponse(event.response),
          usage: event.response?.usage || null,
          model: event.response?.model || model
        };
      }
    }

    if (done) {
      break;
    }
  }

  if (!finalResult.text.trim()) {
    throw new Error("The model response was empty.");
  }

  return finalResult;
}

function parseSseEvent(chunk) {
  const lines = String(chunk || "")
    .split("\n")
    .map((line) => line.trim())
    .filter(Boolean);

  const dataLines = lines
    .filter((line) => line.startsWith("data:"))
    .map((line) => line.slice(5).trim());

  if (!dataLines.length) {
    return null;
  }

  const raw = dataLines.join("\n");
  if (raw === "[DONE]") {
    return raw;
  }

  try {
    return JSON.parse(raw);
  } catch (error) {
    return null;
  }
}

function extractStreamDelta(event) {
  if (!event || typeof event !== "object") {
    return "";
  }

  if (event.type === "response.output_text.delta" && typeof event.delta === "string") {
    return event.delta;
  }

  if (typeof event.delta === "string" && /delta/i.test(String(event.type || ""))) {
    return event.delta;
  }

  return "";
}

function extractTextFromResponse(data) {
  if (!data) {
    return "";
  }

  if (typeof data.output_text === "string" && data.output_text.trim()) {
    return data.output_text.trim();
  }

  const chunks = [];
  for (const item of Array.isArray(data.output) ? data.output : []) {
    for (const content of Array.isArray(item?.content) ? item.content : []) {
      const value = content?.text || content?.output_text || content?.value || "";
      if (typeof value === "string" && value.trim()) {
        chunks.push(value.trim());
      }
    }
  }
  return chunks.join("\n").trim();
}
