package executor

import (
	"encoding/json"
	"math"
	"testing"

	"github.com/everything-on-mysql/cassandra-on-mysql/pkg/cql/types"
)

func TestDecodeCollectionJSON(t *testing.T) {
	translator := NewQueryResultTranslator()

	listBytes := translator.translateValue([]string{"a", "b"}, "list<text>", nil)
	decodedList, err := decodeCQLValue(listBytes, "list<text>", nil)
	if err != nil {
		t.Fatalf("decodeCQLValue list failed: %v", err)
	}
	listJSON, ok := decodedList.([]byte)
	if !ok {
		t.Fatalf("expected JSON bytes for list, got %T", decodedList)
	}
	var listOut []interface{}
	if err := json.Unmarshal(listJSON, &listOut); err != nil {
		t.Fatalf("list JSON unmarshal failed: %v", err)
	}
	if len(listOut) != 2 || listOut[0] != "a" || listOut[1] != "b" {
		t.Fatalf("unexpected list JSON output: %#v", listOut)
	}

	mapBytes := translator.translateValue(map[int]string{1: "x", 2: "y"}, "map<int, text>", nil)
	decodedMap, err := decodeCQLValue(mapBytes, "map<int, text>", nil)
	if err != nil {
		t.Fatalf("decodeCQLValue map failed: %v", err)
	}
	mapJSON, ok := decodedMap.([]byte)
	if !ok {
		t.Fatalf("expected JSON bytes for map, got %T", decodedMap)
	}
	var mapOut map[string]interface{}
	if err := json.Unmarshal(mapJSON, &mapOut); err != nil {
		t.Fatalf("map JSON unmarshal failed: %v", err)
	}
	if mapOut["1"] != "x" || mapOut["2"] != "y" {
		t.Fatalf("unexpected map JSON output: %#v", mapOut)
	}
}

func TestDecodeUDTWithVectorJSON(t *testing.T) {
	translator := NewQueryResultTranslator()
	vectorInfo := &types.VectorTypeInfo{ElemType: "float", Size: 2}
	udtInfo := &types.UDTTypeInfo{
		Keyspace: "ks",
		Name:     "vec_udt",
		Fields: []types.UDTField{
			{Name: "id", Type: "int"},
			{Name: "embedding", Type: "vector<float, 2>", TypeInfo: vectorInfo},
		},
	}

	raw := translator.writeUDTValue(map[string]interface{}{
		"id":        int32(5),
		"embedding": []float32{1.5, -2},
	}, udtInfo)
	decoded, err := decodeCQLValue(raw, "vec_udt", udtInfo)
	if err != nil {
		t.Fatalf("decodeCQLValue UDT failed: %v", err)
	}
	jsonBytes, ok := decoded.([]byte)
	if !ok {
		t.Fatalf("expected JSON bytes, got %T", decoded)
	}
	var out map[string]interface{}
	if err := json.Unmarshal(jsonBytes, &out); err != nil {
		t.Fatalf("UDT JSON unmarshal failed: %v", err)
	}
	if out["id"] != float64(5) {
		t.Fatalf("unexpected id value: %#v", out["id"])
	}
	emb, ok := out["embedding"].([]interface{})
	if !ok || len(emb) != 2 {
		t.Fatalf("unexpected embedding value: %#v", out["embedding"])
	}
	if math.Abs(emb[0].(float64)-1.5) > 1e-6 || math.Abs(emb[1].(float64)+2) > 1e-6 {
		t.Fatalf("unexpected embedding values: %#v", emb)
	}
}

func TestDecodeVectorValueLength(t *testing.T) {
	info := &types.VectorTypeInfo{ElemType: "float", Size: 2}
	good := make([]byte, 8)
	if _, err := decodeVectorValue(good, "vector<float, 2>", info); err != nil {
		t.Fatalf("expected vector length to be valid: %v", err)
	}
	bad := make([]byte, 4)
	if _, err := decodeVectorValue(bad, "vector<float, 2>", info); err == nil {
		t.Fatalf("expected vector length validation error")
	}
}
