package activityapi

import (
	"context"

	userv1 "hyapp.local/api/proto/user/v1"
	walletv1 "hyapp.local/api/proto/wallet/v1"
	"hyapp/pkg/userleaderboard"
	"hyapp/services/gateway-service/internal/appconfig"
	"hyapp/services/gateway-service/internal/client"
	"hyapp/services/gateway-service/internal/transport/http/httproutes"
)

// Handler owns activity-facing HTTP endpoints.
// It keeps task and registration reward reads/writes behind activity-service, with gateway only adding auth context.
type Handler struct {
	taskClient           client.TaskClient
	growthLevelClient    client.GrowthLevelClient
	achievementClient    client.AchievementClient
	userProfileClient    UserProfileReader
	roomQueryClient      client.RoomQueryClient
	walletClient         ActivityWalletClient
	userLeaderboard      UserLeaderboardStore
	runtimeCapabilities  appconfig.RuntimeCapabilityReader
	registrationReward   client.RegistrationRewardClient
	firstRechargeReward  client.FirstRechargeRewardClient
	cumulativeRecharge   client.CumulativeRechargeRewardClient
	inviteActivityReward client.InviteActivityRewardClient
	sevenDayCheckIn      client.SevenDayCheckInClient
	luckyGift            client.LuckyGiftClient
	roomTurnoverReward   client.RoomTurnoverRewardClient
	weeklyStar           client.WeeklyStarClient
	cpWeeklyRank         client.CPWeeklyRankClient
	agencyOpening        client.AgencyOpeningClient
	wheel                client.WheelClient

	activityTemplateRuntime client.ActivityTemplateRuntimeClient
}

type UserLeaderboardStore interface {
	List(ctx context.Context, query userleaderboard.Query) (userleaderboard.Page, error)
	RankForUser(ctx context.Context, query userleaderboard.Query, userID int64) (userleaderboard.Entry, bool, error)
}

// UserProfileReader keeps activity HTTP composition on the two profile operations it actually needs.
// The concrete gRPC client exposes more user commands, but widening this boundary would let activity handlers
// accidentally mutate user ownership while only resolving a trusted region and leaderboard presentation data.
type UserProfileReader interface {
	GetUser(ctx context.Context, req *userv1.GetUserRequest) (*userv1.GetUserResponse, error)
	BatchGetUsers(ctx context.Context, req *userv1.BatchGetUsersRequest) (*userv1.BatchGetUsersResponse, error)
}

// ActivityWalletClient 只开放活动模块现有的礼物目录、转盘扣款和榜单展示能力，避免 HTTP handler 获得完整账务接口。
type ActivityWalletClient interface {
	BatchGetUserEquippedResources(ctx context.Context, req *walletv1.BatchGetUserEquippedResourcesRequest) (*walletv1.BatchGetUserEquippedResourcesResponse, error)
	GetResource(ctx context.Context, req *walletv1.GetResourceRequest) (*walletv1.GetResourceResponse, error)
	GetResourceGroup(ctx context.Context, req *walletv1.GetResourceGroupRequest) (*walletv1.GetResourceGroupResponse, error)
	ListGiftConfigs(ctx context.Context, req *walletv1.ListGiftConfigsRequest) (*walletv1.ListGiftConfigsResponse, error)
	DebitWheelDraw(ctx context.Context, req *walletv1.DebitWheelDrawRequest) (*walletv1.DebitWheelDrawResponse, error)
}

type Config struct {
	TaskClient           client.TaskClient
	GrowthLevelClient    client.GrowthLevelClient
	AchievementClient    client.AchievementClient
	UserProfileClient    UserProfileReader
	RoomQueryClient      client.RoomQueryClient
	WalletClient         client.WalletClient
	UserLeaderboard      UserLeaderboardStore
	RuntimeCapabilities  appconfig.RuntimeCapabilityReader
	RegistrationReward   client.RegistrationRewardClient
	FirstRechargeReward  client.FirstRechargeRewardClient
	CumulativeRecharge   client.CumulativeRechargeRewardClient
	InviteActivityReward client.InviteActivityRewardClient
	SevenDayCheckIn      client.SevenDayCheckInClient
	LuckyGift            client.LuckyGiftClient
	RoomTurnoverReward   client.RoomTurnoverRewardClient
	WeeklyStar           client.WeeklyStarClient
	CPWeeklyRank         client.CPWeeklyRankClient
	AgencyOpening        client.AgencyOpeningClient
	Wheel                client.WheelClient

	ActivityTemplateRuntime client.ActivityTemplateRuntimeClient
}

func New(config Config) *Handler {
	return &Handler{
		taskClient:           config.TaskClient,
		growthLevelClient:    config.GrowthLevelClient,
		achievementClient:    config.AchievementClient,
		userProfileClient:    config.UserProfileClient,
		roomQueryClient:      config.RoomQueryClient,
		walletClient:         config.WalletClient,
		userLeaderboard:      config.UserLeaderboard,
		runtimeCapabilities:  config.RuntimeCapabilities,
		registrationReward:   config.RegistrationReward,
		firstRechargeReward:  config.FirstRechargeReward,
		cumulativeRecharge:   config.CumulativeRecharge,
		inviteActivityReward: config.InviteActivityReward,
		sevenDayCheckIn:      config.SevenDayCheckIn,
		luckyGift:            config.LuckyGift,
		roomTurnoverReward:   config.RoomTurnoverReward,
		weeklyStar:           config.WeeklyStar,
		cpWeeklyRank:         config.CPWeeklyRank,
		agencyOpening:        config.AgencyOpening,
		wheel:                config.Wheel,

		activityTemplateRuntime: config.ActivityTemplateRuntime,
	}
}

func (h *Handler) TaskHandlers() httproutes.TaskHandlers {
	return httproutes.TaskHandlers{
		ListTaskTabs:                      h.listTaskTabs,
		ClaimTaskReward:                   h.claimTaskReward,
		GetRegistrationRewardEligibility:  h.getRegistrationRewardEligibility,
		GetFirstRechargeRewardStatus:      h.getFirstRechargeRewardStatus,
		GetCumulativeRechargeRewardStatus: h.getCumulativeRechargeRewardStatus,
		GetInviteActivityRewardStatus:     h.getInviteActivityRewardStatus,
		ClaimInviteActivityReward:         h.claimInviteActivityReward,
		ListInviteActivityLeaderboard:     h.listInviteActivityLeaderboard,
		ListInviteActivityInvitees:        h.listInviteActivityInvitees,
		GetSevenDayCheckInStatus:          h.getSevenDayCheckInStatus,
		SignSevenDayCheckIn:               h.signSevenDayCheckIn,
		ListUserLeaderboards:              h.listUserLeaderboards,
		CheckLuckyGift:                    h.checkLuckyGift,
		GetRoomTurnoverRewardStatus:       h.getRoomTurnoverRewardStatus,
		GetWeeklyStarCurrent:              h.getWeeklyStarCurrent,
		ListWeeklyStarLeaderboard:         h.listWeeklyStarLeaderboard,
		ListWeeklyStarHistory:             h.listWeeklyStarHistory,
		GetCPWeeklyRankStatus:             h.getCPWeeklyRankStatus,
		GetAgencyOpeningStatus:            h.getAgencyOpeningStatus,
		ApplyAgencyOpening:                h.applyAgencyOpening,
		ListAgencyOpeningLeaderboard:      h.listAgencyOpeningLeaderboard,
		GetWheelConfig:                    h.getWheelConfig,
		DrawWheel:                         h.drawWheel,
		ListWheelHistory:                  h.listWheelHistory,
		ListWheelHints:                    h.listWheelHints,

		GetCurrentActivityTemplate:           h.getCurrentActivityTemplate,
		VisitActivityTemplate:                h.visitActivityTemplate,
		ListActivityTemplateTasks:            h.listActivityTemplateTasks,
		ClaimActivityTemplateTask:            h.claimActivityTemplateTask,
		ListActivityTemplateDailyLeaderboard: h.listActivityTemplateDailyLeaderboard,
		ListActivityTemplateTotalLeaderboard: h.listActivityTemplateTotalLeaderboard,
	}
}

func (h *Handler) LevelHandlers() httproutes.LevelHandlers {
	return httproutes.LevelHandlers{
		GetMyLevelOverview: h.getMyLevelOverview,
		GetLevelTrack:      h.getLevelTrack,
		ListLevelRewards:   h.listLevelRewards,
	}
}

func (h *Handler) AchievementHandlers() httproutes.AchievementHandlers {
	return httproutes.AchievementHandlers{
		ListAchievements: h.listAchievements,
		ListMyBadges:     h.listMyBadges,
		SetBadgeDisplay:  h.setBadgeDisplay,
	}
}
