package activityapi

import (
	"net/http"
	"strings"

	activityv1 "hyapp.local/api/proto/activity/v1"
	"hyapp/services/gateway-service/internal/auth"
	"hyapp/services/gateway-service/internal/transport/http/httpkit"
)

type firstRechargeRewardTierData struct {
	TierID          int64                         `json:"tier_id"`
	TierCode        string                        `json:"tier_code"`
	TierName        string                        `json:"tier_name"`
	MinCoinAmount   int64                         `json:"min_coin_amount"`
	MaxCoinAmount   int64                         `json:"max_coin_amount"`
	USDMinorAmount  int64                         `json:"usd_minor_amount"`
	GoogleProductID string                        `json:"google_product_id"`
	DiscountPercent int32                         `json:"discount_percent"`
	ResourceGroupID int64                         `json:"resource_group_id"`
	ResourceGroup   *checkinResourceGroupData     `json:"resource_group,omitempty"`
	Rewards         []firstRechargeRewardItemData `json:"rewards"`
	Status          string                        `json:"status"`
	SortOrder       int32                         `json:"sort_order"`
}

type firstRechargeRewardItemData struct {
	ResourceID        int64  `json:"resource_id,omitempty"`
	ResourceType      string `json:"resource_type"`
	ResourceName      string `json:"resource_name"`
	CoverURL          string `json:"cover_url"`
	AssetURL          string `json:"asset_url"`
	EffectURL         string `json:"effect_url"`
	DurationMS        int64  `json:"duration_ms"`
	Quantity          int64  `json:"quantity"`
	WalletAssetType   string `json:"wallet_asset_type,omitempty"`
	WalletAssetAmount int64  `json:"wallet_asset_amount,omitempty"`
}

type firstRechargeRewardClaimData struct {
	ClaimID            string `json:"claim_id"`
	TransactionID      string `json:"transaction_id"`
	UserID             int64  `json:"user_id"`
	TierID             int64  `json:"tier_id"`
	TierCode           string `json:"tier_code"`
	ResourceGroupID    int64  `json:"resource_group_id"`
	RechargeCoinAmount int64  `json:"recharge_coin_amount"`
	RechargeSequence   int64  `json:"recharge_sequence"`
	RechargeType       string `json:"recharge_type"`
	TierUSDMinorAmount int64  `json:"tier_usd_minor_amount"`
	GoogleProductID    string `json:"google_product_id"`
	RechargeUSDMinor   int64  `json:"recharge_usd_minor"`
	Status             string `json:"status"`
	WalletGrantID      string `json:"wallet_grant_id"`
	FailureReason      string `json:"failure_reason"`
	RechargedAtMS      int64  `json:"recharged_at_ms"`
	GrantedAtMS        int64  `json:"granted_at_ms"`
	CreatedAtMS        int64  `json:"created_at_ms"`
	UpdatedAtMS        int64  `json:"updated_at_ms"`
}

type firstRechargeRewardStatusData struct {
	Enabled      bool                           `json:"enabled"`
	Tiers        []firstRechargeRewardTierData  `json:"tiers"`
	Rewarded     bool                           `json:"rewarded"`
	Claim        *firstRechargeRewardClaimData  `json:"claim,omitempty"`
	Claims       []firstRechargeRewardClaimData `json:"claims"`
	ServerTimeMS int64                          `json:"server_time_ms"`
}

func (h *Handler) getFirstRechargeRewardStatus(writer http.ResponseWriter, request *http.Request) {
	if h.firstRechargeReward == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	resp, err := h.firstRechargeReward.GetFirstRechargeRewardStatus(request.Context(), &activityv1.GetFirstRechargeRewardStatusRequest{
		Meta:   httpkit.ActivityMeta(request),
		UserId: auth.UserIDFromContext(request.Context()),
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	status := resp.GetStatus()
	groups, ok := h.resolveCheckinResourceGroups(writer, request, firstRechargeRewardGroupIDs(status))
	if !ok {
		return
	}
	httpkit.WriteOK(writer, request, firstRechargeRewardStatusFromProto(status, groups))
}

func firstRechargeRewardStatusFromProto(item *activityv1.FirstRechargeRewardStatus, groups map[int64]checkinResourceGroupData) firstRechargeRewardStatusData {
	if item == nil {
		return firstRechargeRewardStatusData{Tiers: []firstRechargeRewardTierData{}, Claims: []firstRechargeRewardClaimData{}}
	}
	tiers := make([]firstRechargeRewardTierData, 0, len(item.GetTiers()))
	for _, tier := range item.GetTiers() {
		tiers = append(tiers, firstRechargeRewardTierFromProto(tier, groups))
	}
	var claim *firstRechargeRewardClaimData
	if item.GetClaim() != nil {
		converted := firstRechargeRewardClaimFromProto(item.GetClaim())
		claim = &converted
	}
	claims := make([]firstRechargeRewardClaimData, 0, len(item.GetClaims()))
	for _, item := range item.GetClaims() {
		claims = append(claims, firstRechargeRewardClaimFromProto(item))
	}
	return firstRechargeRewardStatusData{
		Enabled:      item.GetEnabled(),
		Tiers:        tiers,
		Rewarded:     item.GetRewarded(),
		Claim:        claim,
		Claims:       claims,
		ServerTimeMS: item.GetServerTimeMs(),
	}
}

func firstRechargeRewardTierFromProto(item *activityv1.FirstRechargeRewardTier, groups map[int64]checkinResourceGroupData) firstRechargeRewardTierData {
	if item == nil {
		return firstRechargeRewardTierData{}
	}
	data := firstRechargeRewardTierData{
		TierID:          item.GetTierId(),
		TierCode:        item.GetTierCode(),
		TierName:        item.GetTierName(),
		MinCoinAmount:   item.GetMinCoinAmount(),
		MaxCoinAmount:   item.GetMaxCoinAmount(),
		USDMinorAmount:  item.GetUsdMinorAmount(),
		GoogleProductID: item.GetGoogleProductId(),
		DiscountPercent: item.GetDiscountPercent(),
		ResourceGroupID: item.GetResourceGroupId(),
		Status:          item.GetStatus(),
		SortOrder:       item.GetSortOrder(),
	}
	if group, ok := groups[item.GetResourceGroupId()]; ok {
		data.ResourceGroup = &group
		data.Rewards = firstRechargeRewardItemsFromGroup(group)
	}
	if data.Rewards == nil {
		data.Rewards = []firstRechargeRewardItemData{}
	}
	return data
}

func firstRechargeRewardClaimFromProto(item *activityv1.FirstRechargeRewardClaim) firstRechargeRewardClaimData {
	if item == nil {
		return firstRechargeRewardClaimData{}
	}
	return firstRechargeRewardClaimData{
		ClaimID:            item.GetClaimId(),
		TransactionID:      item.GetTransactionId(),
		UserID:             item.GetUserId(),
		TierID:             item.GetTierId(),
		TierCode:           item.GetTierCode(),
		ResourceGroupID:    item.GetResourceGroupId(),
		RechargeCoinAmount: item.GetRechargeCoinAmount(),
		RechargeSequence:   item.GetRechargeSequence(),
		RechargeType:       item.GetRechargeType(),
		TierUSDMinorAmount: item.GetTierUsdMinorAmount(),
		GoogleProductID:    item.GetGoogleProductId(),
		RechargeUSDMinor:   item.GetRechargeUsdMinor(),
		Status:             item.GetStatus(),
		WalletGrantID:      item.GetWalletGrantId(),
		FailureReason:      item.GetFailureReason(),
		RechargedAtMS:      item.GetRechargedAtMs(),
		GrantedAtMS:        item.GetGrantedAtMs(),
		CreatedAtMS:        item.GetCreatedAtMs(),
		UpdatedAtMS:        item.GetUpdatedAtMs(),
	}
}

func firstRechargeRewardGroupIDs(item *activityv1.FirstRechargeRewardStatus) []int64 {
	if item == nil {
		return nil
	}
	ids := make([]int64, 0, len(item.GetTiers()))
	for _, tier := range item.GetTiers() {
		if tier.GetResourceGroupId() > 0 {
			ids = append(ids, tier.GetResourceGroupId())
		}
	}
	return ids
}

func firstRechargeRewardItemsFromGroup(group checkinResourceGroupData) []firstRechargeRewardItemData {
	items := make([]firstRechargeRewardItemData, 0, len(group.Items))
	for _, item := range group.Items {
		reward := firstRechargeRewardItemData{
			ResourceID:        item.ResourceID,
			DurationMS:        item.DurationMS,
			Quantity:          item.Quantity,
			WalletAssetType:   item.WalletAssetType,
			WalletAssetAmount: item.WalletAssetAmount,
		}
		if item.Resource != nil {
			reward.ResourceType = item.Resource.ResourceType
			reward.ResourceName = item.Resource.Name
			// 首充弹窗格子只展示静态封面，点击后才播放资源资产；因此优先把 preview_url 下发为 cover_url，
			// asset_url 保持资源主资产原值，effect_url 继续兜底旧客户端使用的动画预览字段。
			reward.CoverURL = firstRechargeFirstNonEmpty(item.Resource.PreviewURL, item.Resource.AssetURL, item.Resource.AnimationURL)
			reward.AssetURL = firstRechargeFirstNonEmpty(item.Resource.AssetURL, item.Resource.AnimationURL)
			reward.EffectURL = firstRechargeFirstNonEmpty(item.Resource.AnimationURL, item.Resource.AssetURL, item.Resource.PreviewURL)
		} else {
			reward.ResourceType = firstRechargeWalletAssetType(item.WalletAssetType)
			reward.ResourceName = firstRechargeWalletAssetType(item.WalletAssetType)
			reward.Quantity = firstRechargePositiveOr(item.WalletAssetAmount, item.Quantity)
		}
		items = append(items, reward)
	}
	return items
}

func firstRechargeWalletAssetType(value string) string {
	normalized := strings.ToLower(strings.TrimSpace(value))
	if normalized == "" {
		return "wallet_asset"
	}
	if normalized == "coin" || normalized == "coins" {
		return "coin"
	}
	return normalized
}

func firstRechargePositiveOr(primary int64, fallback int64) int64 {
	if primary > 0 {
		return primary
	}
	return fallback
}

func firstRechargeFirstNonEmpty(values ...string) string {
	for _, value := range values {
		if normalized := strings.TrimSpace(value); normalized != "" {
			return normalized
		}
	}
	return ""
}
