package action

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

	"github.com/stretchr/testify/require"
)

func TestRetrieveMemoryActivity_Query(t *testing.T) {
	// Mock memory service
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/memory/query" {
			resp := map[string]interface{}{
				"results": []map[string]interface{}{
					{
						"id":    "doc-1",
						"level": "L1",
						"score": 0.95,
						"text":  "Security scanning best practices: always check for hardcoded secrets",
					},
					{
						"id":    "doc-2",
						"level": "L2",
						"score": 0.85,
						"text":  "Use gosec for Go security analysis",
					},
				},
			}
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(resp)
			return
		}
		http.NotFound(w, r)
	}))
	defer server.Close()

	// Set env for test
	t.Setenv("POIMEN_MEMORY_URL", server.URL)

	output, err := RetrieveMemoryActivity(context.Background(), RetrieveMemoryInput{
		Query:   "security scanning",
		Project: "poimen",
		Scope:   "lessons",
		Limit:   5,
	})
	require.NoError(t, err)

	require.Equal(t, 2, len(output.Lessons))
	require.Equal(t, "L1", output.Lessons[0].Level)
	require.Contains(t, output.Lessons[0].Text, "Security scanning")
}

func TestRetrieveMemoryActivity_Context(t *testing.T) {
	// Mock memory service with context endpoint
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/memory/context" {
			resp := map[string]interface{}{
				"tier": 1,
				"skills": []map[string]interface{}{
					{
						"name": "security-analysis",
						"why":  "User is asking about security scanning",
					},
				},
				"lessons": []map[string]interface{}{
					{
						"tier":  1,
						"level": "L1",
						"score": 0.9,
						"text":  "Always scan dependencies for vulnerabilities",
					},
				},
				"budget": map[string]interface{}{
					"requested": 8192,
					"used":      1024,
				},
			}
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(resp)
			return
		}
		if r.URL.Path == "/memory/query" {
			resp := map[string]interface{}{"results": []interface{}{}}
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(resp)
			return
		}
		http.NotFound(w, r)
	}))
	defer server.Close()

	t.Setenv("POIMEN_MEMORY_URL", server.URL)

	output, err := RetrieveMemoryActivity(context.Background(), RetrieveMemoryInput{
		Query: "security scan repo",
		Tool:  "poimen-router",
		Task:  "generate workflow for security scanning",
	})
	require.NoError(t, err)

	require.Equal(t, 1, len(output.Skills))
	require.Equal(t, "security-analysis", output.Skills[0].Name)
	require.Equal(t, 1, len(output.Lessons))
	require.Equal(t, 8192, output.Budget.Requested)
	require.Equal(t, 1024, output.Budget.Used)
}

func TestFormatMemoryForPrompt(t *testing.T) {
	mem := RetrieveMemoryOutput{
		Skills: []MemorySkill{
			{Name: "security-scan", Description: "Run security scanner", Why: "Matches user intent"},
		},
		Lessons: []MemoryLesson{
			{ID: "1", Level: "L1", Text: "Always check dependencies"},
		},
		TotalResults: 2,
	}

	result := FormatMemoryForPrompt(mem)

	require.Contains(t, result, "## Relevant Skills")
	require.Contains(t, result, "security-scan")
	require.Contains(t, result, "## Relevant Knowledge")
	require.Contains(t, result, "Always check dependencies")
}

func TestFormatMemoryForPrompt_Empty(t *testing.T) {
	mem := RetrieveMemoryOutput{
		TotalResults: 0,
	}

	result := FormatMemoryForPrompt(mem)
	require.Equal(t, "", result)
}
