package service

import (
	"encoding/json"
	"kra/internal/biz/system"
	"testing"
	"time"

	"kra/internal/service/dto"
)

func TestMenuDomainPreservesRelationIdentity(t *testing.T) {
	createdAt := time.Date(2025, time.March, 4, 5, 6, 7, 0, time.UTC)
	updatedAt := time.Date(2025, time.April, 5, 6, 7, 8, 0, time.UTC)
	menu := menuDomain(&dto.MenuRequest{
		CreatedAt: createdAt,
		UpdatedAt: updatedAt,
		ID:        10,
		MenuButtons: []dto.MenuButtonRequest{{
			CreatedAt: createdAt, UpdatedAt: updatedAt, ID: 31, Name: "edit", Description: "编辑",
		}},
		Parameters: []dto.MenuParameterRequest{{
			CreatedAt: createdAt, UpdatedAt: updatedAt, ID: 21, Type: "query", Key: "id", Value: "1",
		}},
	})
	if !menu.CreatedAt.Equal(createdAt) || !menu.UpdatedAt.Equal(updatedAt) {
		t.Fatalf("menu timestamps = (%v, %v), want (%v, %v)", menu.CreatedAt, menu.UpdatedAt, createdAt, updatedAt)
	}
	if len(menu.Buttons) != 1 || menu.Buttons[0].ID != 31 || menu.Buttons[0].MenuID != 10 || !menu.Buttons[0].CreatedAt.Equal(createdAt) || !menu.Buttons[0].UpdatedAt.Equal(updatedAt) {
		t.Fatalf("button conversion = %+v", menu.Buttons)
	}
	if len(menu.Parameters) != 1 || menu.Parameters[0].ID != 21 || menu.Parameters[0].MenuID != 10 || !menu.Parameters[0].CreatedAt.Equal(createdAt) || !menu.Parameters[0].UpdatedAt.Equal(updatedAt) {
		t.Fatalf("parameter conversion = %+v", menu.Parameters)
	}
}

func TestMenuResponseEmptyCollectionContracts(t *testing.T) {
	if got := menuResponses(nil); got != nil {
		t.Fatalf("base menu top-level nil = %#v, want nil", got)
	}
	if got := dynamicMenuResponses(nil); got == nil || len(got) != 0 {
		t.Fatalf("dynamic menu top-level empty = %#v, want non-nil empty slice", got)
	}

	base := menuResponse(&system.Menu{Children: nil, Buttons: []*system.MenuButton{}, Parameters: []*system.MenuParameter{}})
	if base.Children != nil {
		t.Fatalf("leaf children = %#v, want nil", base.Children)
	}
	if base.MenuButtons == nil || base.Parameters == nil {
		t.Fatalf("preloaded empty relations = (%#v, %#v), want empty slices", base.MenuButtons, base.Parameters)
	}
	encoded, err := json.Marshal(base)
	if err != nil {
		t.Fatal(err)
	}
	var payload map[string]any
	if err := json.Unmarshal(encoded, &payload); err != nil {
		t.Fatal(err)
	}
	if value, ok := payload["authoritys"]; !ok || value != nil {
		t.Fatalf("authoritys JSON = %#v (present=%v), want explicit null", value, ok)
	}
}
