package responses

import (
	"bytes"
	"context"
	"fmt"

	"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
	"github.com/tidwall/gjson"
	"github.com/tidwall/sjson"
)

// ConvertCodexResponseToOpenAIResponses converts OpenAI Chat Completions streaming chunks
// to OpenAI Responses SSE events (response.*).

func ConvertCodexResponseToOpenAIResponses(ctx context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string {
	if bytes.HasPrefix(rawJSON, []byte("data:")) {
		rawJSON = bytes.TrimSpace(rawJSON[5:])
		if typeResult := gjson.GetBytes(rawJSON, "type"); typeResult.Exists() {
			typeStr := typeResult.String()
			if typeStr == "response.created" || typeStr == "response.in_progress" || typeStr == "response.completed" {
				if gjson.GetBytes(rawJSON, "response.instructions").Exists() {
					instructions := selectInstructions(originalRequestRawJSON, requestRawJSON)
					rawJSON, _ = sjson.SetBytes(rawJSON, "response.instructions", instructions)
				}
			}
		}
		out := fmt.Sprintf("data: %s", string(rawJSON))
		return []string{out}
	}
	return []string{string(rawJSON)}
}

// ConvertCodexResponseToOpenAIResponsesNonStream builds a single Responses JSON
// from a non-streaming OpenAI Chat Completions response.
func ConvertCodexResponseToOpenAIResponsesNonStream(_ context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, _ *any) string {
	rootResult := gjson.ParseBytes(rawJSON)
	// Verify this is a response.completed event
	if rootResult.Get("type").String() != "response.completed" {
		return ""
	}
	responseResult := rootResult.Get("response")
	template := responseResult.Raw
	if responseResult.Get("instructions").Exists() {
		template, _ = sjson.Set(template, "instructions", selectInstructions(originalRequestRawJSON, requestRawJSON))
	}
	return template
}

func selectInstructions(originalRequestRawJSON, requestRawJSON []byte) string {
	userAgent := misc.ExtractCodexUserAgent(originalRequestRawJSON)
	if misc.IsOpenCodeUserAgent(userAgent) {
		return gjson.GetBytes(requestRawJSON, "instructions").String()
	}
	return gjson.GetBytes(originalRequestRawJSON, "instructions").String()
}
