package memory

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

func TestClientIngest(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/memory/ingest" {
			t.Errorf("unexpected path: %s", r.URL.Path)
		}

		if r.Header.Get("Authorization") == "" {
			t.Error("missing Authorization header")
		}

		w.WriteHeader(http.StatusCreated)
		json.NewEncoder(w).Encode(IngestResponse{
			ID:          "chunk-123",
			SHA256:      "abc123",
			QueueStatus: "pending",
		})
	}))
	defer server.Close()

	client := NewClient(server.URL, "test-token")
	resp, err := client.Ingest(context.Background(), &IngestRequest{
		Project: "poimen",
		Source:  "test",
		Kind:    "L1",
		Text:    "test content",
	})

	if err != nil {
		t.Fatalf("ingest failed: %v", err)
	}

	if resp.ID != "chunk-123" {
		t.Errorf("expected ID chunk-123, got %s", resp.ID)
	}
}

func TestClientQuery(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/memory/query" {
			t.Errorf("unexpected path: %s", r.URL.Path)
		}

		w.WriteHeader(http.StatusOK)
		json.NewEncoder(w).Encode(QueryResponse{
			Query:        "test query",
			TotalHits:    1,
			SearchTimeMS: 100,
			Results: []QueryResult{
				{
					ID:    "chunk-123",
					Level: "L1",
					Score: 0.95,
					Text:  "matching result",
				},
			},
		})
	}))
	defer server.Close()

	client := NewClient(server.URL, "test-token")
	resp, err := client.Query(context.Background(), &QueryRequest{
		Project: "poimen",
		Query:   "test query",
		Limit:   10,
	})

	if err != nil {
		t.Fatalf("query failed: %v", err)
	}

	if len(resp.Results) != 1 {
		t.Errorf("expected 1 result, got %d", len(resp.Results))
	}

	if resp.Results[0].Text != "matching result" {
		t.Errorf("unexpected result text")
	}
}

func TestClientContext(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/memory/context" {
			t.Errorf("unexpected path: %s", r.URL.Path)
		}

		w.WriteHeader(http.StatusOK)
		json.NewEncoder(w).Encode(ContextResponse{
			Tier: 1,
			Lessons: []ContextLesson{
				{
					Tier:  1,
					Level: "L1",
					Score: 1.0,
					Text:  "tier-1 lesson",
				},
			},
			Budget: ContextBudget{
				Requested: 8192,
				Used:      100,
				Dropped:   0,
			},
		})
	}))
	defer server.Close()

	client := NewClient(server.URL, "test-token")
	resp, err := client.Context(context.Background(), &ContextRequest{
		Project:         "poimen",
		Tool:            "kubectl",
		Task:            "debug",
		SignatureSource: "log",
	})

	if err != nil {
		t.Fatalf("context failed: %v", err)
	}

	if resp.Tier != 1 {
		t.Errorf("expected tier 1, got %d", resp.Tier)
	}

	if len(resp.Lessons) != 1 {
		t.Errorf("expected 1 lesson, got %d", len(resp.Lessons))
	}
}

func TestClientVault(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/memory/vault" {
			t.Errorf("unexpected path: %s", r.URL.Path)
		}

		w.WriteHeader(http.StatusOK)
		json.NewEncoder(w).Encode(VaultResponse{
			Project:      "poimen",
			TotalRecords: 42,
			Files: []VaultFile{
				{
					Path:        "test.md",
					Title:       "Test",
					Level:       "L1",
					RecordCount: 5,
				},
			},
		})
	}))
	defer server.Close()

	client := NewClient(server.URL, "test-token")
	resp, err := client.Vault(context.Background(), "poimen")

	if err != nil {
		t.Fatalf("vault failed: %v", err)
	}

	if len(resp.Files) != 1 {
		t.Errorf("expected 1 file, got %d", len(resp.Files))
	}

	if resp.TotalRecords != 42 {
		t.Errorf("expected 42 records, got %d", resp.TotalRecords)
	}
}

func TestClientHealth(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/health" {
			t.Errorf("unexpected path: %s", r.URL.Path)
		}

		w.WriteHeader(http.StatusOK)
		json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
	}))
	defer server.Close()

	client := NewClient(server.URL, "test-token")
	ok, err := client.Health(context.Background())

	if err != nil {
		t.Fatalf("health check failed: %v", err)
	}

	if !ok {
		t.Error("expected health check to pass")
	}
}
