package walletapi

import (
	"net/http"

	walletv1 "hyapp.local/api/proto/wallet/v1"
	"hyapp/pkg/appcode"
	"hyapp/services/gateway-service/internal/auth"
	"hyapp/services/gateway-service/internal/transport/http/httpkit"
)

type vipSettingsPatchBody struct {
	// 指针保留 PATCH 的三态：未提交、显式 true、显式 false。
	RoomEntryNoticeEnabled       *bool `json:"room_entry_notice_enabled"`
	OnlineGlobalNoticeEnabled    *bool `json:"online_global_notice_enabled"`
	HideProfileDataEnabled       *bool `json:"hide_profile_data_enabled"`
	AnonymousProfileVisitEnabled *bool `json:"anonymous_profile_visit_enabled"`
	LeaderboardInvisibleEnabled  *bool `json:"leaderboard_invisible_enabled"`
}

// handleVIPSettings 在同一路径分发 GET/PATCH，避免向当前 ServeMux 重复注册相同 pattern。
func (h *Handler) handleVIPSettings(writer http.ResponseWriter, request *http.Request) {
	switch request.Method {
	case http.MethodGet:
		h.getVIPSettings(writer, request)
	case http.MethodPatch:
		h.patchVIPSettings(writer, request)
	default:
		httpkit.WriteError(writer, request, http.StatusMethodNotAllowed, httpkit.CodeInvalidArgument, "invalid argument")
	}
}

// getVIPSettings 复用 GetMyVip 的同一状态快照，不为 room/online 开关再发第二个 wallet RPC。
func (h *Handler) getVIPSettings(writer http.ResponseWriter, request *http.Request) {
	if h.walletClient == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	ctx := request.Context()
	appCode := appcode.FromContext(ctx)
	userID := auth.UserIDFromContext(ctx)
	resp, err := h.walletClient.GetMyVip(ctx, &walletv1.GetMyVipRequest{
		RequestId: httpkit.RequestIDFromContext(ctx), AppCode: appCode, UserId: userID,
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	if resp == nil || resp.GetState() == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	settings := vipUserSettingsFromProto(resp.GetState().GetUserSettings())
	// 兼容滚动升级期间旧 wallet 未返回 settings 标识字段；默认布尔值仍由 converter 保持开启。
	if settings.AppCode == "" {
		settings.AppCode = appCode
	}
	if settings.UserID == 0 {
		settings.UserID = userID
	}
	httpkit.WriteOK(writer, request, map[string]any{
		"settings": settings, "evaluated_at_ms": resp.GetState().GetEvaluatedAtMs(),
	})
}

// patchVIPSettings 只从鉴权上下文取 app/user，客户端不能替他人或跨 App 改设置。
func (h *Handler) patchVIPSettings(writer http.ResponseWriter, request *http.Request) {
	if h.walletClient == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	var body vipSettingsPatchBody
	if !httpkit.Decode(writer, request, &body) {
		return
	}
	if body.RoomEntryNoticeEnabled == nil && body.OnlineGlobalNoticeEnabled == nil &&
		body.HideProfileDataEnabled == nil && body.AnonymousProfileVisitEnabled == nil &&
		body.LeaderboardInvisibleEnabled == nil {
		httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
		return
	}
	ctx := request.Context()
	resp, err := h.walletClient.UpdateMyVipSettings(ctx, &walletv1.UpdateMyVipSettingsRequest{
		RequestId: httpkit.RequestIDFromContext(ctx), AppCode: appcode.FromContext(ctx),
		UserId: auth.UserIDFromContext(ctx), RoomEntryNoticeEnabled: body.RoomEntryNoticeEnabled,
		OnlineGlobalNoticeEnabled:    body.OnlineGlobalNoticeEnabled,
		HideProfileDataEnabled:       body.HideProfileDataEnabled,
		AnonymousProfileVisitEnabled: body.AnonymousProfileVisitEnabled,
		LeaderboardInvisibleEnabled:  body.LeaderboardInvisibleEnabled,
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	if resp == nil || resp.GetSettings() == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	httpkit.WriteOK(writer, request, map[string]any{
		"settings": vipUserSettingsFromProto(resp.GetSettings()), "server_time_ms": resp.GetServerTimeMs(),
	})
}
