package userapi

import (
	"context"
	"net/http"
	"strconv"
	"strings"
	"time"

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

type hostEngagementStatsClient interface {
	GetHostEngagementStats(context.Context, *userv1.GetHostEngagementStatsRequest) (*userv1.GetHostEngagementStatsResponse, error)
}

type hostRevenueStatsClient interface {
	GetHostRevenueStats(context.Context, *walletv1.GetHostRevenueStatsRequest) (*walletv1.GetHostRevenueStatsResponse, error)
}

const hostCenterMaxStatsDays = 366

type hostCenterStatsRangeData struct {
	StartDate string `json:"start_date"`
	EndDate   string `json:"end_date"`
	Timezone  string `json:"timezone"`
}

type hostCenterStatsMetricsData struct {
	PolicyType            string `json:"policy_type"`
	DiamondEarnings       string `json:"diamond_earnings"`
	DiamondExchanged      string `json:"diamond_exchanged"`
	SalaryDiamondEarnings string `json:"salary_diamond_earnings"`
	LegacyPointExchanged  string `json:"legacy_point_exchanged"`
	PointDiamondEarnings  string `json:"point_diamond_earnings"`
	PointDiamondExchanged string `json:"point_diamond_exchanged"`
	GiftSenders           int64  `json:"gift_senders"`
	OnlineDurationMS      int64  `json:"online_duration_ms"`
	ValidMicDurationMS    int64  `json:"valid_mic_duration_ms"`
	ValidMicDays          int64  `json:"valid_mic_days"`
	PrivateMessageSenders int64  `json:"private_message_senders"`
	NewFollowers          int64  `json:"new_followers"`
}

// getHostCenterStats 只编排 user/wallet 两个 owner 的只读聚合，不在 gateway 重算账务或在线时长。
func (h *Handler) getHostCenterStats(writer http.ResponseWriter, request *http.Request) {
	profile, ok := h.resolveCurrentActiveHostProfile(writer, request)
	if !ok {
		return
	}
	engagementClient, engagementOK := h.userHostClient.(hostEngagementStatsClient)
	revenueClient, revenueOK := h.walletClient.(hostRevenueStatsClient)
	if !engagementOK || !revenueOK {
		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
	}

	engagementResp, err := engagementClient.GetHostEngagementStats(request.Context(), &userv1.GetHostEngagementStatsRequest{
		Meta:       httpkit.UserMeta(request, ""),
		HostUserId: profile.GetUserId(),
		StartAtMs:  startAtMS,
		EndAtMs:    endAtMS,
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	revenueResp, err := revenueClient.GetHostRevenueStats(request.Context(), &walletv1.GetHostRevenueStatsRequest{
		RequestId:  httpkit.RequestIDFromContext(request.Context()),
		AppCode:    appcode.FromContext(request.Context()),
		HostUserId: profile.GetUserId(),
		RegionId:   profile.GetRegionId(),
		StartAtMs:  startAtMS,
		EndAtMs:    endAtMS,
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	policyResp, err := h.walletClient.GetActiveHostSalaryPolicy(request.Context(), &walletv1.GetActiveHostSalaryPolicyRequest{
		RequestId: httpkit.RequestIDFromContext(request.Context()), AppCode: appcode.FromContext(request.Context()),
		RegionId: profile.GetRegionId(), CycleKey: time.Now().UTC().Format("2006-01"),
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	engagement := engagementResp.GetStats()
	revenue := revenueResp.GetStats()
	metrics := hostCenterRevenueMetrics(revenue, policyResp.GetPolicy().GetPolicyType())
	metrics.GiftSenders = revenue.GetGiftSenders()
	metrics.OnlineDurationMS = engagement.GetOnlineDurationMs()
	metrics.ValidMicDurationMS = engagement.GetValidMicDurationMs()
	metrics.ValidMicDays = engagement.GetValidMicDays()
	metrics.PrivateMessageSenders = engagement.GetPrivateMessageSenders()
	metrics.NewFollowers = engagement.GetNewFollowers()
	httpkit.WriteOK(writer, request, map[string]any{
		"range":   hostCenterStatsRangeData{StartDate: startDate, EndDate: endDate, Timezone: "UTC"},
		"metrics": metrics,
	})
}

func hostCenterRevenueMetrics(revenue *walletv1.HostRevenueStats, policyType string) hostCenterStatsMetricsData {
	salaryEarnings := revenue.GetDiamondEarnings()
	legacyExchanged := revenue.GetDiamondExchanged()
	pointEarnings := revenue.GetPointDiamondEarnings()
	pointExchanged := revenue.GetPointDiamondExchanged()
	selectedEarnings, selectedExchanged := salaryEarnings, legacyExchanged
	if strings.EqualFold(strings.TrimSpace(policyType), "POINT_DIAMOND") {
		selectedEarnings, selectedExchanged = pointEarnings, pointExchanged
	}
	result := hostCenterStatsMetricsData{
		PolicyType:            policyType,
		SalaryDiamondEarnings: strconv.FormatInt(salaryEarnings, 10), LegacyPointExchanged: strconv.FormatInt(legacyExchanged, 10),
		PointDiamondEarnings: strconv.FormatInt(pointEarnings, 10), PointDiamondExchanged: strconv.FormatInt(pointExchanged, 10),
		DiamondEarnings: strconv.FormatInt(selectedEarnings, 10), DiamondExchanged: strconv.FormatInt(selectedExchanged, 10),
	}
	return result
}

func parseHostCenterStatsRange(request *http.Request) (string, string, int64, int64, bool) {
	startText := strings.TrimSpace(request.URL.Query().Get("start_date"))
	endText := strings.TrimSpace(request.URL.Query().Get("end_date"))
	if startText == "" || endText == "" {
		return "", "", 0, 0, false
	}
	start, startErr := time.Parse("2006-01-02", startText)
	end, endErr := time.Parse("2006-01-02", endText)
	if startErr != nil || endErr != nil || end.Before(start) {
		return "", "", 0, 0, false
	}
	endExclusive := end.Add(24 * time.Hour)
	if int(endExclusive.Sub(start)/(24*time.Hour)) > hostCenterMaxStatsDays {
		return "", "", 0, 0, false
	}
	return startText, endText, start.UnixMilli(), endExclusive.UnixMilli(), true
}
