package clients

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"sync/atomic"
	"testing"

	"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
)

func TestOpenAIImageEndpointsRemoveRejectedResponseFormatAndCacheCorrection(t *testing.T) {
	for _, test := range []struct {
		name string
		kind string
		body map[string]any
	}{
		{
			name: "generation JSON",
			kind: "images.generations",
			body: map[string]any{"prompt": "test", "response_format": "url"},
		},
		{
			name: "edit multipart",
			kind: "images.edits",
			body: map[string]any{"prompt": "test", "image": "aW1hZ2U=", "response_format": "url"},
		},
	} {
		t.Run(test.name, func(t *testing.T) {
			var requests atomic.Int32
			server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				requestNo := requests.Add(1)
				responseFormat := ""
				if test.kind == "images.edits" {
					if err := r.ParseMultipartForm(1 << 20); err != nil {
						t.Fatalf("parse multipart image request: %v", err)
					}
					responseFormat = r.FormValue("response_format")
				} else {
					var body map[string]any
					if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
						t.Fatalf("decode image request: %v", err)
					}
					responseFormat, _ = body["response_format"].(string)
				}
				if requestNo == 1 {
					if responseFormat != "url" {
						t.Fatalf("first request lost caller response_format: %q", responseFormat)
					}
					w.Header().Set("Content-Type", "application/json")
					w.WriteHeader(http.StatusBadRequest)
					_ = json.NewEncoder(w).Encode(map[string]any{"error": map[string]any{
						"message": "Unknown parameter: 'response_format'.",
						"type":    "invalid_request_error", "param": "response_format", "code": "unknown_parameter",
					}})
					return
				}
				if responseFormat != "" {
					t.Fatalf("corrected request still contains response_format: %q", responseFormat)
				}
				w.Header().Set("Content-Type", "application/json")
				_ = json.NewEncoder(w).Encode(map[string]any{"data": []any{map[string]any{"b64_json": "aW1hZ2U="}}})
			}))
			defer server.Close()

			cache := NewParameterCorrectionCache()
			request := Request{
				Kind: test.kind, Model: "gpt-image-2", Body: test.body, OriginalBody: test.body,
				UpstreamIdempotencyKey: "gateway-task-id",
				Candidate: store.RuntimeModelCandidate{
					Provider: "openai", BaseURL: server.URL, ProviderModelName: "gpt-image-2",
					Credentials: map[string]any{"apiKey": "test-key"},
				},
			}
			client := OpenAIClient{HTTPClient: server.Client(), Corrections: cache}
			if _, err := client.Run(context.Background(), request); err != nil {
				t.Fatalf("correct rejected response_format: %v", err)
			}
			if requests.Load() != 2 {
				t.Fatalf("first corrected call requests=%d, want 2", requests.Load())
			}
			if _, err := client.Run(context.Background(), request); err != nil {
				t.Fatalf("reuse cached response_format correction: %v", err)
			}
			if requests.Load() != 3 {
				t.Fatalf("cached correction should avoid another 400, requests=%d", requests.Load())
			}
		})
	}
}
