package domain

import (
	"encoding/json"
	"testing"
)

func TestJSONMapValue(t *testing.T) {
	t.Run("nil map returns nil database value", func(t *testing.T) {
		var payload JSONMap

		value, err := payload.Value()
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		if value != nil {
			t.Fatalf("expected nil value, got %v", value)
		}
	})

	t.Run("map marshals to JSON string", func(t *testing.T) {
		payload := JSONMap{"enabled": true, "name": "baron"}

		value, err := payload.Value()
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		raw, ok := value.(string)
		if !ok {
			t.Fatalf("expected string value, got %T", value)
		}

		var decoded map[string]any
		if err := json.Unmarshal([]byte(raw), &decoded); err != nil {
			t.Fatalf("value should be valid json: %v", err)
		}
		if decoded["enabled"] != true || decoded["name"] != "baron" {
			t.Fatalf("unexpected decoded value: %#v", decoded)
		}
	})
}

func TestJSONMapScan(t *testing.T) {
	t.Run("nil value becomes empty map", func(t *testing.T) {
		var payload JSONMap

		if err := payload.Scan(nil); err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		if payload == nil || len(payload) != 0 {
			t.Fatalf("expected empty map, got %#v", payload)
		}
	})

	t.Run("byte slice value decodes JSON", func(t *testing.T) {
		var payload JSONMap

		if err := payload.Scan([]byte(`{"count":2,"name":"baron"}`)); err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		if payload["count"] != float64(2) || payload["name"] != "baron" {
			t.Fatalf("unexpected payload: %#v", payload)
		}
	})

	t.Run("string value decodes JSON", func(t *testing.T) {
		var payload JSONMap

		if err := payload.Scan(`{"active":true}`); err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		if payload["active"] != true {
			t.Fatalf("unexpected payload: %#v", payload)
		}
	})

	t.Run("unsupported value type returns error", func(t *testing.T) {
		var payload JSONMap

		if err := payload.Scan(42); err == nil {
			t.Fatalf("expected unsupported type error")
		}
	})

	t.Run("invalid JSON returns error", func(t *testing.T) {
		var payload JSONMap

		if err := payload.Scan(`{invalid`); err == nil {
			t.Fatalf("expected invalid JSON error")
		}
	})
}
