package userapi

import (
	"context"
	"net/http"
	"sync"

	userv1 "hyapp.local/api/proto/user/v1"
	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 agencyHostGiftStatsClient interface {
	GetAgencyHostGiftStats(context.Context, *walletv1.GetAgencyHostGiftStatsRequest) (*walletv1.GetAgencyHostGiftStatsResponse, error)
}

type bdCenterAgencyStatsData struct {
	Agency          hostAgencyData       `json:"agency"`
	Owner           agencyCenterUserData `json:"owner"`
	Country         string               `json:"country"`
	TotalHosts      int                  `json:"total_hosts"`
	GiftedHostCount int64                `json:"gifted_host_count"`
	DiamondEarnings int64                `json:"diamond_earnings"`
	JoinedAtMS      int64                `json:"joined_at_ms"`
}

// getBDCenterStats 返回 BD 直属 Agency 的收礼统计；工资和 Agency 分成不属于设计稿口径，刻意不返回。
func (h *Handler) getBDCenterStats(writer http.ResponseWriter, request *http.Request) {
	userID := auth.UserIDFromContext(request.Context())
	if _, ok := h.resolveActiveBD(writer, request, userID); !ok {
		return
	}
	statsClient, ok := h.walletClient.(agencyHostGiftStatsClient)
	if !ok {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	startDate, endDate, startAtMS, endAtMS, ok := parseHostCenterStatsRange(request)
	if !ok {
		httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid date range")
		return
	}
	agenciesResp, err := h.userHostClient.ListBDAgencies(request.Context(), &userv1.ListBDAgenciesRequest{
		Meta: httpkit.UserMeta(request, ""), BdUserId: userID, Status: agencyStatusActive, PageSize: 100,
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	ownerIDs := make([]int64, 0, len(agenciesResp.GetAgencies()))
	for _, agency := range agenciesResp.GetAgencies() {
		ownerIDs = append(ownerIDs, agency.GetOwnerUserId())
	}
	owners, err := h.userProfiles(request, ownerIDs)
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}

	items := make([]bdCenterAgencyStatsData, len(agenciesResp.GetAgencies()))
	ctx, cancel := context.WithCancel(request.Context())
	defer cancel()
	semaphore := make(chan struct{}, 8)
	var wait sync.WaitGroup
	var firstErr error
	var errorMu sync.Mutex
	for index, agency := range agenciesResp.GetAgencies() {
		index, agency := index, agency
		wait.Add(1)
		go func() {
			defer wait.Done()
			semaphore <- struct{}{}
			defer func() { <-semaphore }()
			members, callErr := h.userHostClient.GetAgencyMembers(ctx, &userv1.GetAgencyMembersRequest{
				Meta: httpkit.UserMeta(request, ""), AgencyId: agency.GetAgencyId(), Status: membershipStatusActive,
			})
			hostIDs := make([]int64, 0, len(members.GetMemberships()))
			if callErr == nil {
				for _, membership := range members.GetMemberships() {
					hostIDs = append(hostIDs, membership.GetHostUserId())
				}
				var stats *walletv1.GetAgencyHostGiftStatsResponse
				stats, callErr = statsClient.GetAgencyHostGiftStats(ctx, &walletv1.GetAgencyHostGiftStatsRequest{
					RequestId: httpkit.RequestIDFromContext(request.Context()), AppCode: appcode.FromContext(request.Context()),
					HostUserIds: hostIDs, StartAtMs: startAtMS, EndAtMs: endAtMS,
				})
				if callErr == nil {
					owner := owners[agency.GetOwnerUserId()]
					items[index] = bdCenterAgencyStatsData{
						Agency: hostAgencyFromProto(agency), Owner: owner, Country: owner.Country,
						TotalHosts: len(hostIDs), GiftedHostCount: stats.GetStats().GetGiftedHostCount(),
						DiamondEarnings: bdCenterAgencyHostIncome(stats.GetStats()), JoinedAtMS: agency.GetCreatedAtMs(),
					}
				}
			}
			if callErr != nil {
				errorMu.Lock()
				if firstErr == nil {
					firstErr = callErr
					cancel()
				}
				errorMu.Unlock()
			}
		}()
	}
	wait.Wait()
	if firstErr != nil {
		httpkit.WriteRPCError(writer, request, firstErr)
		return
	}
	httpkit.WriteOK(writer, request, map[string]any{
		"range": hostCenterStatsRangeData{StartDate: startDate, EndDate: endDate, Timezone: "UTC"},
		"items": items, "total": len(items),
	})
}

// bdCenterAgencyHostIncome 合并工资型与永久积分型 Host 礼物投影，覆盖政策切换前后的查询区间；
// Agency 分成和已结算工资属于其他口径，不能混入 BD 页面展示的 Agency Host 总收入。
func bdCenterAgencyHostIncome(stats *walletv1.AgencyHostGiftStats) int64 {
	if stats == nil {
		return 0
	}
	return stats.GetGiftIncome() + stats.GetPointDiamondHostIncome()
}
