package service

import (
	"database/sql"
	"encoding/json"
	"testing"

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

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

	summary := &model.RequestSummary{}
	applyStoredResponseToSummary(summary, sql.NullString{
		Valid:  true,
		String: `{"statusCode":201,"responseTime":42,"body":{"usage":{"input_tokens":10,"output_tokens":5},"stop_reason":"end_turn"}}`,
	})

	if summary.StatusCode != 201 {
		t.Fatalf("expected status code 201, got %d", summary.StatusCode)
	}
	if summary.ResponseTime != 42 {
		t.Fatalf("expected response time 42, got %d", summary.ResponseTime)
	}
	if summary.Usage == nil || summary.Usage.InputTokens != 10 || summary.Usage.OutputTokens != 5 {
		t.Fatalf("expected usage decoded, got %#v", summary.Usage)
	}
	if summary.StopReason != "end_turn" {
		t.Fatalf("expected stop reason end_turn, got %q", summary.StopReason)
	}
}

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

	summary := &model.RequestSummary{}
	applyStoredResponseToSummary(summary, sql.NullString{Valid: true, String: `{not-json`})

	if summary.StatusCode != 0 || summary.ResponseTime != 0 || summary.Usage != nil || summary.StopReason != "" {
		t.Fatalf("expected invalid payload ignored, got %#v", summary)
	}
}

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

	body, _ := json.Marshal(map[string]interface{}{
		"usage": map[string]interface{}{
			"input_tokens":                7,
			"output_tokens":               3,
			"cache_read_input_tokens":     2,
			"cache_creation_input_tokens": 1,
		},
		"stop_reason": "tool_use",
	})

	summary, ok := decodeResponseBodySummary(body)
	if !ok {
		t.Fatal("expected response body summary to decode")
	}
	if total := totalTokensFromUsage(summary.Usage); total != 13 {
		t.Fatalf("expected total tokens 13, got %d", total)
	}
	if summary.StopReason != "tool_use" {
		t.Fatalf("expected stop reason tool_use, got %q", summary.StopReason)
	}
}

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

	input, output, cache, ok := usageCountsFromStoredResponse(sql.NullString{
		Valid:  true,
		String: `{"body":{"usage":{"input_tokens":7,"output_tokens":3,"cache_read_input_tokens":2,"cache_creation_input_tokens":1}}}`,
	})
	if !ok {
		t.Fatal("expected usage counts to decode")
	}
	if input != 7 || output != 3 || cache != 3 {
		t.Fatalf("unexpected usage counts: input=%d output=%d cache=%d", input, output, cache)
	}
}
