package resource

import (
	"strings"

	"hyapp/services/wallet-service/internal/domain/ledger"
)

const (
	TypeAvatarFrame    = "avatar_frame"
	TypeProfileCard    = "profile_card"
	TypeCoin           = "coin"
	TypeVehicle        = "vehicle"
	TypeChatBubble     = "chat_bubble"
	TypeBadge          = "badge"
	TypeFloatingScreen = "floating_screen"
	TypeGift           = "gift"

	StatusActive   = "active"
	StatusDisabled = "disabled"

	GrantStrategyWalletCredit     = "wallet_credit"
	GrantStrategyNewEntitlement   = "new_entitlement"
	GrantStrategyExtendExpiry     = "extend_expiry"
	GrantStrategyIncreaseQuantity = "increase_quantity"
	GrantStrategySetActiveFlag    = "set_active_flag"

	GrantSubjectResource = "resource"
	GrantSubjectGroup    = "resource_group"

	GrantSourceAdmin         = "admin"
	GrantSourceManagerCenter = "manager_center"
	GrantStatusDone          = "succeeded"
	ResultWalletCredit       = "wallet_credit"
	ResultEntitlement        = "entitlement"

	GroupItemTypeResource    = "resource"
	GroupItemTypeWalletAsset = "wallet_asset"

	GiftTypeNormal     = "normal"
	GiftTypeCP         = "cp"
	GiftTypeLucky      = "lucky"
	GiftTypeSuperLucky = "super_lucky"
	GiftTypeExclusive  = "exclusive"
	GiftTypeNoble      = "noble"
	GiftTypeFlag       = "flag"
	GiftTypeActivity   = "activity"
	GiftTypeMagic      = "magic"
	GiftTypeCustom     = "custom"

	GiftEffectAnimation       = "animation"
	GiftEffectMusic           = "music"
	GiftEffectGlobalBroadcast = "global_broadcast"
)

type Resource struct {
	AppCode             string
	ResourceID          int64
	ResourceCode        string
	ResourceType        string
	Name                string
	Status              string
	Grantable           bool
	GrantStrategy       string
	WalletAssetType     string
	WalletAssetAmount   int64
	UsageScopes         []string
	AssetURL            string
	PreviewURL          string
	AnimationURL        string
	MetadataJSON        string
	SortOrder           int32
	CreatedByUserID     int64
	UpdatedByUserID     int64
	CreatedAtMS         int64
	UpdatedAtMS         int64
	ManagerGrantEnabled bool
}

type ResourceGroupItem struct {
	GroupItemID       int64
	GroupID           int64
	ItemType          string
	ResourceID        int64
	Resource          Resource
	WalletAssetType   string
	WalletAssetAmount int64
	Quantity          int64
	DurationMS        int64
	SortOrder         int32
	CreatedAtMS       int64
	UpdatedAtMS       int64
}

type ResourceGroup struct {
	AppCode         string
	GroupID         int64
	GroupCode       string
	Name            string
	Status          string
	Description     string
	SortOrder       int32
	Items           []ResourceGroupItem
	CreatedByUserID int64
	UpdatedByUserID int64
	CreatedAtMS     int64
	UpdatedAtMS     int64
}

type GiftConfig struct {
	AppCode          string
	GiftID           string
	ResourceID       int64
	Resource         Resource
	Status           string
	Name             string
	SortOrder        int32
	PresentationJSON string
	PriceVersion     string
	CoinPrice        int64
	GiftPointAmount  int64
	HeatValue        int64
	GiftTypeCode     string
	ChargeAssetType  string
	EffectiveFromMS  int64
	EffectiveToMS    int64
	EffectTypes      []string
	CreatedByUserID  int64
	UpdatedByUserID  int64
	CreatedAtMS      int64
	UpdatedAtMS      int64
	RegionIDs        []int64
}

type UserResourceEntitlement struct {
	AppCode           string
	EntitlementID     string
	UserID            int64
	ResourceID        int64
	Resource          Resource
	Status            string
	Quantity          int64
	RemainingQuantity int64
	EffectiveAtMS     int64
	ExpiresAtMS       int64
	SourceGrantID     string
	CreatedAtMS       int64
	UpdatedAtMS       int64
}

type ResourceGrantItem struct {
	GrantItemID          int64
	GrantID              string
	ResourceID           int64
	ResourceSnapshotJSON string
	Quantity             int64
	DurationMS           int64
	ResultType           string
	WalletTransactionID  string
	EntitlementID        string
	CreatedAtMS          int64
}

type ResourceGrant struct {
	AppCode          string
	GrantID          string
	CommandID        string
	TargetUserID     int64
	GrantSource      string
	GrantSubjectType string
	GrantSubjectID   string
	Status           string
	Reason           string
	OperatorUserID   int64
	Items            []ResourceGrantItem
	CreatedAtMS      int64
	UpdatedAtMS      int64
}

type ListResourcesQuery struct {
	AppCode          string
	ResourceType     string
	Status           string
	Keyword          string
	Page             int32
	PageSize         int32
	ActiveOnly       bool
	ManagerGrantOnly bool
}

type ResourceCommand struct {
	AppCode             string
	ResourceID          int64
	ResourceCode        string
	ResourceType        string
	Name                string
	Status              string
	Grantable           bool
	GrantStrategy       string
	WalletAssetType     string
	WalletAssetAmount   int64
	UsageScopes         []string
	AssetURL            string
	PreviewURL          string
	AnimationURL        string
	MetadataJSON        string
	SortOrder           int32
	OperatorUserID      int64
	ManagerGrantEnabled bool
}

type StatusCommand struct {
	AppCode        string
	ID             int64
	StringID       string
	Status         string
	OperatorUserID int64
}

type ResourceGroupItemInput struct {
	ItemType          string
	ResourceID        int64
	WalletAssetType   string
	WalletAssetAmount int64
	Quantity          int64
	DurationMS        int64
	SortOrder         int32
}

type ListResourceGroupsQuery struct {
	AppCode    string
	Status     string
	Keyword    string
	Page       int32
	PageSize   int32
	ActiveOnly bool
}

type ResourceGroupCommand struct {
	AppCode        string
	GroupID        int64
	GroupCode      string
	Name           string
	Status         string
	Description    string
	SortOrder      int32
	Items          []ResourceGroupItemInput
	OperatorUserID int64
}

type ListGiftConfigsQuery struct {
	AppCode      string
	Status       string
	Keyword      string
	Page         int32
	PageSize     int32
	ActiveOnly   bool
	RegionID     int64
	FilterRegion bool
}

type GiftConfigCommand struct {
	AppCode          string
	GiftID           string
	ResourceID       int64
	Status           string
	Name             string
	SortOrder        int32
	PresentationJSON string
	PriceVersion     string
	CoinPrice        int64
	GiftPointAmount  int64
	HeatValue        int64
	EffectiveAtMS    int64
	GiftTypeCode     string
	ChargeAssetType  string
	EffectiveFromMS  int64
	EffectiveToMS    int64
	EffectTypes      []string
	OperatorUserID   int64
	RegionIDs        []int64
}

type GrantResourceCommand struct {
	AppCode        string
	CommandID      string
	TargetUserID   int64
	ResourceID     int64
	Quantity       int64
	DurationMS     int64
	Reason         string
	OperatorUserID int64
	GrantSource    string
}

type GrantResourceGroupCommand struct {
	AppCode        string
	CommandID      string
	TargetUserID   int64
	GroupID        int64
	Reason         string
	OperatorUserID int64
	GrantSource    string
}

type ListUserResourcesQuery struct {
	AppCode      string
	UserID       int64
	ResourceType string
	ActiveOnly   bool
}

type EquipUserResourceCommand struct {
	AppCode       string
	UserID        int64
	ResourceID    int64
	EntitlementID string
}

type ListResourceGrantsQuery struct {
	AppCode      string
	TargetUserID int64
	Status       string
	Page         int32
	PageSize     int32
}

func NormalizeStatus(value string) string {
	value = strings.ToLower(strings.TrimSpace(value))
	if value == "" {
		return StatusActive
	}
	return value
}

func NormalizeGrantSource(value string) string {
	value = strings.ToLower(strings.TrimSpace(value))
	if value == "" {
		return GrantSourceAdmin
	}
	return value
}

func ValidResourceType(value string) bool {
	switch strings.ToLower(strings.TrimSpace(value)) {
	case TypeAvatarFrame, TypeProfileCard, TypeCoin, TypeVehicle, TypeChatBubble, TypeBadge, TypeFloatingScreen, TypeGift:
		return true
	default:
		return false
	}
}

func ValidStatus(value string) bool {
	switch NormalizeStatus(value) {
	case StatusActive, StatusDisabled:
		return true
	default:
		return false
	}
}

func ValidGrantStrategy(value string) bool {
	switch strings.ToLower(strings.TrimSpace(value)) {
	case GrantStrategyWalletCredit, GrantStrategyNewEntitlement, GrantStrategyExtendExpiry, GrantStrategyIncreaseQuantity, GrantStrategySetActiveFlag:
		return true
	default:
		return false
	}
}

func NormalizeGroupItemType(value string) string {
	value = strings.ToLower(strings.TrimSpace(value))
	if value == "" {
		return GroupItemTypeResource
	}
	return value
}

func ValidGroupItemType(value string) bool {
	switch NormalizeGroupItemType(value) {
	case GroupItemTypeResource, GroupItemTypeWalletAsset:
		return true
	default:
		return false
	}
}

func NormalizeResourceType(value string) string {
	return strings.ToLower(strings.TrimSpace(value))
}

func NormalizeGrantStrategy(value string) string {
	return strings.ToLower(strings.TrimSpace(value))
}

func NormalizeWalletAssetType(value string) string {
	return strings.ToUpper(strings.TrimSpace(value))
}

func NormalizeGiftTypeCode(value string) string {
	value = strings.ToLower(strings.TrimSpace(value))
	if value == "" {
		return GiftTypeNormal
	}
	return value
}

func ValidGiftTypeCode(value string) bool {
	switch NormalizeGiftTypeCode(value) {
	case GiftTypeNormal, GiftTypeCP, GiftTypeLucky, GiftTypeSuperLucky, GiftTypeExclusive, GiftTypeNoble, GiftTypeFlag, GiftTypeActivity, GiftTypeMagic, GiftTypeCustom:
		return true
	default:
		return false
	}
}

func NormalizeGiftEffectType(value string) string {
	return strings.ToLower(strings.TrimSpace(value))
}

func ValidGiftEffectType(value string) bool {
	switch NormalizeGiftEffectType(value) {
	case GiftEffectAnimation, GiftEffectMusic, GiftEffectGlobalBroadcast:
		return true
	default:
		return false
	}
}

func IsWalletCredit(resource Resource) bool {
	return NormalizeGrantStrategy(resource.GrantStrategy) == GrantStrategyWalletCredit
}

func IsCoinResource(resource Resource) bool {
	return NormalizeResourceType(resource.ResourceType) == TypeCoin
}

func WalletAssetForCoin() string {
	return ledger.AssetCoin
}
