package rest

import (
	"log"
	"reflect"
	"testing"
	"time"

	"git.ali33.ru/fcg-xvii/go-tools/json"
)

func TestFieldsDefault(t *testing.T) {
	type RR struct {
		ID      int64  `rest:"default"`
		Name    string `rest:"default"`
		GroupID int64
	}

	rr := RR{}
	fields := fieldsDefault(reflect.TypeOf(rr))
	expected := []any{"id", "name"}
	if len(fields) != len(expected) {
		t.Errorf("expected %v, real %v", expected, fields)
	}
	for i, val := range expected {
		if fields[i] != val {
			t.Errorf("expected %v, real %v", expected, fields)
		}
	}
}

func TestFielderName(t *testing.T) {
	name := "Name"
	if field, err := parseName(reflect.ValueOf(name)); field.Name != camelToSnake(name) || err != nil {
		if err != nil {
			t.Error(err)
		}
		t.Errorf("expected %v, real %v", camelToSnake(name), field.Name)
	}
	obj := json.Map{
		"name": "Object",
		"fields": []any{
			"okko",
			"cooler",
		},
	}
	field, err := parseName(reflect.ValueOf(obj))
	if err != nil {
		t.Error(err)
	}
	// check name
	if field.Name != "object" {
		t.Errorf("expected %v, real %v", "object", name)
	}
	// check fields
	for i, val := range []any{"okko", "cooler"} {
		if field.Names[i] != val {
			t.Errorf("expected %v, real %v", val, field.Names[i])
		}
	}
}

type RR struct {
	ID      int64  `rest:"default"`
	Name    string `rest:"default"`
	GroupID int64  `rest:"ignore"`
	Child   *RR
	Nums    []int64
	Childs  []*RR
	MM      json.Map
}

func (s *RR) RestFields(result json.Map, fields FieldList) {
	if _, check := fields.Field("group_id"); check {
		result["group_id"] = s.GroupID * 1000
	}
}

func TestFielderVal(t *testing.T) {

	rr := &RR{
		ID:      1,
		Name:    "okko",
		GroupID: 2,
		MM: json.Map{
			"one": 1,
			"obj": &RR{
				ID:   1,
				Name: "mm-obj",
			},
		},
		Child: &RR{
			ID:      3,
			Name:    "cooler",
			GroupID: 4,
		},
		Nums: []int64{1, 2, 3},
		Childs: []*RR{
			{
				ID:      5,
				Name:    "okko1",
				GroupID: 6,
			},
			{
				ID:      7,
				Name:    "cooler1",
				GroupID: 8,
			},
		},
	}

	val, err := fieldVal(
		reflect.ValueOf(rr),
		"",
		nil,
		"id",
		"name",
		"nums",
		"group_id",
		"mm",
		json.Map{
			"name":   "childs",
			"fields": []any{"id", "name", "childs"},
		},
		json.Map{
			"name":   "child",
			"fields": []any{"id"},
		},
	)
	if err != nil {
		t.Error(err, err.Args())
	}

	m := val.Interface().(json.Map)
	m.LogPretty()

	mVal, err := Fields(
		rr,
		nil,
		"id",
		"name",
		"nums",
		"mm",
		"group_id",
		json.Map{
			"name":   "childs",
			"fields": []any{"id", "name", "childs"},
		},
		json.Map{
			"name":   "child",
			"fields": []any{"id"},
		},
	)
	if err != nil {
		t.Error(err, err.Args())
	}
	log.Println("========================================")
	mVal.LogPretty()
}

type RTime struct {
	Time
}

type TimeObj struct {
	Created RTime `rest:"default"`
}

func TestTime(t *testing.T) {
	obj := TimeObj{
		Created: RTime{Time(time.Now())},
	}
	log.Println(obj)
	f, _ := Fields(&obj, nil)
	f.LogPretty()

	var rObj TimeObj
	if err := Serialize(f, &rObj); err != nil {
		t.Fatal(err.Map().JSONPrettyString())
	}
	log.Println(rObj)
	jm := json.Map{
		"created": 12321311,
	}
	if err := Serialize(jm, &rObj); err != nil {
		t.Fatal(err.Map().JSONPrettyString())
	}
	t.Log(rObj)
}