package walletapi

import (
	"hyapp/services/gateway-service/internal/transport/http/httpkit"
	"net/http"
	"strings"

	"hyapp/pkg/appcode"
	"hyapp/services/gateway-service/internal/auth"

	walletv1 "hyapp.local/api/proto/wallet/v1"
)

// getMyVIP 返回当前用户 VIP 状态。
func (h *Handler) getMyVIP(writer http.ResponseWriter, request *http.Request) {
	if h.walletClient == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	resp, err := h.walletClient.GetMyVip(request.Context(), &walletv1.GetMyVipRequest{
		RequestId: httpkit.RequestIDFromContext(request.Context()),
		AppCode:   appcode.FromContext(request.Context()),
		UserId:    auth.UserIDFromContext(request.Context()),
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	httpkit.WriteOK(writer, request, vipFromProto(resp.GetVip()))
}

// listVIPPackages 返回可购买 VIP 包和当前会员状态。
func (h *Handler) listVIPPackages(writer http.ResponseWriter, request *http.Request) {
	if h.walletClient == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	resp, err := h.walletClient.ListVipPackages(request.Context(), &walletv1.ListVipPackagesRequest{
		RequestId: httpkit.RequestIDFromContext(request.Context()),
		AppCode:   appcode.FromContext(request.Context()),
		UserId:    auth.UserIDFromContext(request.Context()),
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	packages := make([]vipPackageData, 0, len(resp.GetPackages()))
	for _, item := range resp.GetPackages() {
		packages = append(packages, vipPackageFromProto(item))
	}
	httpkit.WriteOK(writer, request, map[string]any{"current_vip": vipFromProto(resp.GetCurrentVip()), "packages": packages})
}

// purchaseVIP 购买、续期或升级 VIP。
func (h *Handler) purchaseVIP(writer http.ResponseWriter, request *http.Request) {
	if h.walletClient == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	var body vipPurchaseRequestBody
	if !httpkit.Decode(writer, request, &body) {
		return
	}
	commandID := strings.TrimSpace(body.CommandID)
	if commandID == "" {
		commandID = strings.TrimSpace(body.CommandIDAlt)
	}
	if commandID == "" || body.Level <= 0 {
		httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
		return
	}
	resp, err := h.walletClient.PurchaseVip(request.Context(), &walletv1.PurchaseVipRequest{
		CommandId: commandID,
		AppCode:   appcode.FromContext(request.Context()),
		UserId:    auth.UserIDFromContext(request.Context()),
		Level:     body.Level,
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	httpkit.WriteOK(writer, request, map[string]any{
		"order_id":           resp.GetOrderId(),
		"transaction_id":     resp.GetTransactionId(),
		"vip":                vipFromProto(resp.GetVip()),
		"coin_spent":         resp.GetCoinSpent(),
		"coin_balance_after": resp.GetCoinBalanceAfter(),
		"reward_items":       vipRewardItemsFromProto(resp.GetRewardItems()),
	})
}

func vipFromProto(vip *walletv1.UserVip) overviewVIPData {
	if vip == nil {
		return overviewVIPData{}
	}
	return overviewVIPData{
		Level:       vip.GetLevel(),
		Name:        vip.GetName(),
		Active:      vip.GetActive(),
		StartedAtMS: vip.GetStartedAtMs(),
		ExpiresAtMS: vip.GetExpiresAtMs(),
	}
}

func vipPackageFromProto(item *walletv1.VipLevel) vipPackageData {
	if item == nil {
		return vipPackageData{}
	}
	return vipPackageData{
		Level:                      item.GetLevel(),
		Name:                       item.GetName(),
		Status:                     item.GetStatus(),
		PriceCoin:                  item.GetPriceCoin(),
		DurationMS:                 item.GetDurationMs(),
		RewardResourceGroupID:      item.GetRewardResourceGroupId(),
		RewardItems:                vipRewardItemsFromProto(item.GetRewardItems()),
		CanPurchase:                item.GetCanPurchase(),
		SortOrder:                  item.GetSortOrder(),
		RechargeGateRequired:       item.GetRechargeGateRequired(),
		RequiredRechargeCoinAmount: item.GetRequiredRechargeCoinAmount(),
		UserRechargeCoinAmount:     item.GetUserRechargeCoinAmount(),
		PurchaseLockedReason:       item.GetPurchaseLockedReason(),
	}
}

func vipRewardItemsFromProto(items []*walletv1.VipRewardItem) []vipRewardItemData {
	resp := make([]vipRewardItemData, 0, len(items))
	for _, item := range items {
		if item == nil {
			continue
		}
		resp = append(resp, vipRewardItemData{
			ResourceID:   item.GetResourceId(),
			ResourceCode: item.GetResourceCode(),
			ResourceType: item.GetResourceType(),
			Name:         item.GetName(),
			Quantity:     item.GetQuantity(),
			ExpiresAtMS:  item.GetExpiresAtMs(),
			CoverURL:     vipRewardCoverURL(item),
			AssetURL:     item.GetAssetUrl(),
			PreviewURL:   item.GetPreviewUrl(),
			AnimationURL: item.GetAnimationUrl(),
		})
	}
	return resp
}

func vipRewardCoverURL(item *walletv1.VipRewardItem) string {
	if item == nil {
		return ""
	}
	if strings.TrimSpace(item.GetPreviewUrl()) != "" {
		return item.GetPreviewUrl()
	}
	return item.GetAssetUrl()
}
