package service

import (
	"database/sql"
	"io"
	"log"
	"testing"

	"github.com/seifghazi/claude-code-monitor/internal/model"
)

func TestUnmarshalStoredRequestFields(t *testing.T) {
	t.Parallel()

	logger := log.New(io.Discard, "", 0)

	t.Run("decodes all stored fields", func(t *testing.T) {
		t.Parallel()

		req := &model.RequestLog{}
		err := unmarshalStoredRequestFields(
			logger,
			req,
			`{"content-type":["application/json"]}`,
			`{"messages":[{"role":"user","content":"hi"}]}`,
			sql.NullString{String: `{"score":8,"maxScore":10}`, Valid: true},
			sql.NullString{String: `{"statusCode":200,"body":{"ok":true}}`, Valid: true},
		)
		if err != nil {
			t.Fatalf("unmarshalStoredRequestFields() error = %v", err)
		}
		if got := req.Headers["content-type"][0]; got != "application/json" {
			t.Fatalf("expected header decoded, got %q", got)
		}
		body := req.Body.(map[string]interface{})
		messages := body["messages"].([]interface{})
		if len(messages) != 1 {
			t.Fatalf("expected one message, got %#v", body)
		}
		if req.PromptGrade == nil || req.PromptGrade.Score != 8 {
			t.Fatalf("expected prompt grade decoded, got %#v", req.PromptGrade)
		}
		if req.Response == nil || req.Response.StatusCode != 200 {
			t.Fatalf("expected response decoded, got %#v", req.Response)
		}
	})

	t.Run("returns error for invalid headers json", func(t *testing.T) {
		t.Parallel()

		req := &model.RequestLog{}
		err := unmarshalStoredRequestFields(
			logger,
			req,
			`{not-json`,
			`{"ok":true}`,
			sql.NullString{},
			sql.NullString{},
		)
		if err == nil {
			t.Fatal("expected invalid headers json error")
		}
	})

	t.Run("returns error for invalid body json", func(t *testing.T) {
		t.Parallel()

		req := &model.RequestLog{}
		err := unmarshalStoredRequestFields(
			logger,
			req,
			`{"accept":["application/json"]}`,
			`{not-json`,
			sql.NullString{},
			sql.NullString{},
		)
		if err == nil {
			t.Fatal("expected invalid body json error")
		}
	})

	t.Run("ignores corrupt optional grade and response", func(t *testing.T) {
		t.Parallel()

		req := &model.RequestLog{}
		err := unmarshalStoredRequestFields(
			logger,
			req,
			`{"accept":["application/json"]}`,
			`{"ok":true}`,
			sql.NullString{String: `{"score":`, Valid: true},
			sql.NullString{String: `{"statusCode":`, Valid: true},
		)
		if err != nil {
			t.Fatalf("unmarshalStoredRequestFields() unexpected error = %v", err)
		}
		if req.PromptGrade != nil {
			t.Fatalf("expected corrupt prompt grade ignored, got %#v", req.PromptGrade)
		}
		if req.Response != nil {
			t.Fatalf("expected corrupt response ignored, got %#v", req.Response)
		}
	})
}
