package handlers

import (
	"encoding/json"
	"testing"

	"github.com/gin-gonic/gin"
)

// Contract tests for the new /norms-library/crossref endpoints.
// These are the practical equivalent of an OpenAPI snapshot: they pin
// the response shape so a downstream consumer (admin-compliance,
// developer-portal, SDK) cannot be silently broken.

func TestGetNormCrossRef_KnownID_ReturnsExpectedShape(t *testing.T) {
	handler := &IACEHandler{}
	w, c := newTestContext("GET", "/norms-library/ISO-12100/crossref", nil, nil, gin.Params{
		{Key: "id", Value: "ISO-12100"},
	})

	handler.GetNormCrossRef(c)

	if w.Code != 200 {
		t.Fatalf("expected 200, got %d body=%s", w.Code, w.Body.String())
	}

	var resp struct {
		NormID   string `json:"norm_id"`
		Mappings []struct {
			Region     string `json:"region"`
			Identifier string `json:"identifier"`
			Relation   string `json:"relation"`
			Confidence string `json:"confidence"`
		} `json:"mappings"`
		BatchID string `json:"batch_id"`
	}
	if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
		t.Fatalf("response not parsable: %v body=%s", err, w.Body.String())
	}
	if resp.NormID != "ISO-12100" {
		t.Errorf("expected norm_id ISO-12100, got %q", resp.NormID)
	}
	if len(resp.Mappings) < 3 {
		t.Errorf("expected ISO-12100 to have at least 3 mappings, got %d", len(resp.Mappings))
	}
}

func TestGetNormCrossRef_MissingID_Returns400(t *testing.T) {
	handler := &IACEHandler{}
	w, c := newTestContext("GET", "/norms-library//crossref", nil, nil, gin.Params{
		{Key: "id", Value: ""},
	})

	handler.GetNormCrossRef(c)
	if w.Code != 400 {
		t.Errorf("expected 400 for missing id, got %d", w.Code)
	}
}

func TestGetNormCrossRef_UnknownID_ReturnsEmptyMappings(t *testing.T) {
	handler := &IACEHandler{}
	w, c := newTestContext("GET", "/norms-library/ISO-DOESNOTEXIST/crossref", nil, nil, gin.Params{
		{Key: "id", Value: "ISO-DOESNOTEXIST"},
	})

	handler.GetNormCrossRef(c)

	if w.Code != 200 {
		t.Fatalf("expected 200 for unknown id (returns empty), got %d", w.Code)
	}
	var resp struct {
		NormID   string        `json:"norm_id"`
		Mappings []interface{} `json:"mappings"`
	}
	if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
		t.Fatalf("response not parsable: %v", err)
	}
	if resp.NormID != "ISO-DOESNOTEXIST" {
		t.Errorf("expected norm_id to echo back, got %q", resp.NormID)
	}
	if len(resp.Mappings) != 0 {
		t.Errorf("expected empty mappings, got %d", len(resp.Mappings))
	}
}

func TestListNormCrossRefs_ReturnsAll(t *testing.T) {
	handler := &IACEHandler{}
	w, c := newTestContext("GET", "/norms-library/crossref", nil, nil, nil)

	handler.ListNormCrossRefs(c)

	if w.Code != 200 {
		t.Fatalf("expected 200, got %d", w.Code)
	}
	var resp struct {
		Entries []struct {
			NormID string `json:"norm_id"`
		} `json:"entries"`
		Total int `json:"total"`
	}
	if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
		t.Fatalf("response not parsable: %v", err)
	}
	if resp.Total != 671 {
		t.Errorf("expected 671 cross-ref entries, got %d", resp.Total)
	}
	if len(resp.Entries) != resp.Total {
		t.Errorf("entries count %d does not match total %d", len(resp.Entries), resp.Total)
	}
}
