package gamemanagement

import (
	"strings"
	"time"

	"hyapp-admin-server/internal/appctx"
	"hyapp-admin-server/internal/middleware"
	gamev1 "hyapp.local/api/proto/game/v1"

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

type platformRequest struct {
	PlatformCode string `json:"platformCode"`
	PlatformName string `json:"platformName"`
	Status       string `json:"status"`
	APIBaseURL   string `json:"apiBaseUrl"`
	SortOrder    int32  `json:"sortOrder"`
}

type catalogRequest struct {
	GameID         string   `json:"gameId"`
	PlatformCode   string   `json:"platformCode"`
	ProviderGameID string   `json:"providerGameId"`
	GameName       string   `json:"gameName"`
	Category       string   `json:"category"`
	IconURL        string   `json:"iconUrl"`
	CoverURL       string   `json:"coverUrl"`
	LaunchMode     string   `json:"launchMode"`
	Orientation    string   `json:"orientation"`
	MinCoin        int64    `json:"minCoin"`
	Status         string   `json:"status"`
	SortOrder      int32    `json:"sortOrder"`
	Tags           []string `json:"tags"`
}

type statusRequest struct {
	Status string `json:"status"`
}

func (r platformRequest) toProto(platformCode string) *gamev1.GamePlatform {
	if platformCode == "" {
		platformCode = r.PlatformCode
	}
	return &gamev1.GamePlatform{
		PlatformCode: strings.TrimSpace(platformCode),
		PlatformName: strings.TrimSpace(r.PlatformName),
		Status:       strings.TrimSpace(r.Status),
		ApiBaseUrl:   strings.TrimSpace(r.APIBaseURL),
		SortOrder:    r.SortOrder,
	}
}

func (r catalogRequest) toProto(gameID string) *gamev1.GameCatalogItem {
	if gameID == "" {
		gameID = r.GameID
	}
	return &gamev1.GameCatalogItem{
		GameId:         strings.TrimSpace(gameID),
		PlatformCode:   strings.TrimSpace(r.PlatformCode),
		ProviderGameId: strings.TrimSpace(r.ProviderGameID),
		GameName:       strings.TrimSpace(r.GameName),
		Category:       strings.TrimSpace(r.Category),
		IconUrl:        strings.TrimSpace(r.IconURL),
		CoverUrl:       strings.TrimSpace(r.CoverURL),
		LaunchMode:     strings.TrimSpace(r.LaunchMode),
		Orientation:    strings.TrimSpace(r.Orientation),
		MinCoin:        r.MinCoin,
		Status:         strings.TrimSpace(r.Status),
		SortOrder:      r.SortOrder,
		Tags:           compactTags(r.Tags),
	}
}

func compactTags(tags []string) []string {
	out := make([]string, 0, len(tags))
	seen := make(map[string]struct{}, len(tags))
	for _, tag := range tags {
		value := strings.TrimSpace(tag)
		if value == "" {
			continue
		}
		if _, ok := seen[value]; ok {
			continue
		}
		seen[value] = struct{}{}
		out = append(out, value)
	}
	return out
}

func requestMeta(c *gin.Context) *gamev1.RequestMeta {
	return &gamev1.RequestMeta{
		RequestId:   middleware.CurrentRequestID(c),
		Caller:      "admin-server",
		ActorUserId: int64(middleware.CurrentUserID(c)),
		SentAtMs:    time.Now().UnixMilli(),
		AppCode:     appctx.FromContext(c.Request.Context()),
	}
}
