package http

import (
	"context"
	"hyapp/services/gateway-service/internal/transport/http/httpkit"
	"net/http"
	"sync"
	"time"

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

const overviewAggregationTimeout = 200 * time.Millisecond

type myOverviewData struct {
	Profile      userProfileData      `json:"profile"`
	ProfileStats overviewProfileStats `json:"profile_stats"`
	Wallet       overviewWalletData   `json:"wallet"`
	VIP          overviewVIPData      `json:"vip"`
	Roles        overviewRolesData    `json:"roles"`
	Entries      []overviewEntryData  `json:"entries"`
	ServerTimeMS int64                `json:"server_time_ms"`
}

type overviewWalletData struct {
	CoinAmount  int64 `json:"coin_amount"`
	UpdatedAtMS int64 `json:"updated_at_ms"`
	Unavailable bool  `json:"unavailable,omitempty"`
}

type overviewRolesData struct {
	IsHost                 bool   `json:"is_host"`
	IsAgency               bool   `json:"is_agency"`
	IsBD                   bool   `json:"is_bd"`
	IsBDLeader             bool   `json:"is_bd_leader"`
	IsCoinSeller           bool   `json:"is_coin_seller"`
	HostStatus             string `json:"host_status,omitempty"`
	AgencyID               int64  `json:"agency_id,omitempty"`
	BDID                   int64  `json:"bd_id,omitempty"`
	BDStatus               string `json:"bd_status,omitempty"`
	CoinSellerStatus       string `json:"coin_seller_status,omitempty"`
	PendingRoleInvitations int64  `json:"pending_role_invitations"`
	Unavailable            bool   `json:"unavailable,omitempty"`
}

type overviewProfileStats struct {
	VisitorsCount  int64 `json:"visitors_count"`
	FollowingCount int64 `json:"following_count"`
	FriendsCount   int64 `json:"friends_count"`
	UpdatedAtMS    int64 `json:"updated_at_ms"`
	Unavailable    bool  `json:"unavailable,omitempty"`
}

type overviewEntryData struct {
	Key        string `json:"key"`
	Visible    bool   `json:"visible"`
	Enabled    bool   `json:"enabled"`
	Route      string `json:"route"`
	IconKey    string `json:"icon_key"`
	BadgeCount int64  `json:"badge_count"`
	Order      int32  `json:"order"`
}

type overviewVIPData struct {
	Level       int32  `json:"level"`
	Name        string `json:"name"`
	Active      bool   `json:"active"`
	StartedAtMS int64  `json:"started_at_ms"`
	ExpiresAtMS int64  `json:"expires_at_ms"`
	Unavailable bool   `json:"unavailable,omitempty"`
}

// getMyOverview 聚合 App 我的页首屏摘要；gateway 只做 RPC 编排和入口显隐规则，不查数据库。
func (h *Handler) getMyOverview(writer http.ResponseWriter, request *http.Request) {
	if h.userProfileClient == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}

	ctx, cancel := context.WithTimeout(request.Context(), overviewAggregationTimeout)
	defer cancel()

	userID := auth.UserIDFromContext(request.Context())
	var wg sync.WaitGroup

	var profileResp *userv1.GetUserResponse
	var profileErr error
	wg.Go(func() {
		profileResp, profileErr = h.userProfileClient.GetUser(ctx, &userv1.GetUserRequest{
			Meta:   authRequestMeta(request.WithContext(ctx), ""),
			UserId: userID,
		})
	})

	var walletResp *walletv1.GetWalletValueSummaryResponse
	var walletErr error
	wg.Go(func() {
		if h.walletClient == nil {
			walletErr = xerr.New(xerr.Unavailable, "wallet service is not configured")
			return
		}
		walletResp, walletErr = h.walletClient.GetWalletValueSummary(ctx, &walletv1.GetWalletValueSummaryRequest{
			RequestId: httpkit.RequestIDFromContext(request.Context()),
			UserId:    userID,
			AppCode:   appcode.FromContext(request.Context()),
		})
	})

	var vipResp *walletv1.GetMyVipResponse
	var vipErr error
	wg.Go(func() {
		if h.walletClient == nil {
			vipErr = xerr.New(xerr.Unavailable, "wallet service is not configured")
			return
		}
		vipResp, vipErr = h.walletClient.GetMyVip(ctx, &walletv1.GetMyVipRequest{
			RequestId: httpkit.RequestIDFromContext(request.Context()),
			UserId:    userID,
			AppCode:   appcode.FromContext(request.Context()),
		})
	})

	var roles overviewRolesData
	var rolesErr error
	wg.Go(func() {
		roles, rolesErr = h.getOverviewRoles(ctx, request, userID)
	})

	var statsResp *userv1.GetMyProfileStatsResponse
	var statsErr error
	wg.Go(func() {
		statsResp, statsErr = h.userProfileClient.GetMyProfileStats(ctx, &userv1.GetMyProfileStatsRequest{
			Meta:   authRequestMeta(request.WithContext(ctx), ""),
			UserId: userID,
		})
	})

	wg.Wait()
	if profileErr != nil {
		httpkit.WriteRPCError(writer, request, profileErr)
		return
	}
	if profileResp.GetUser() == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}

	if rolesErr != nil {
		roles = overviewRolesData{Unavailable: true}
	}
	wallet := overviewWallet(walletResp, walletErr)
	vip := overviewVIP(vipResp, vipErr)
	profileStats := overviewStats(statsResp, statsErr)

	httpkit.WriteOK(writer, request, myOverviewData{
		Profile:      profileData(profileResp.GetUser(), 0),
		ProfileStats: profileStats,
		Wallet:       wallet,
		VIP:          vip,
		Roles:        roles,
		Entries:      overviewEntries(roles),
		ServerTimeMS: time.Now().UnixMilli(),
	})
}

func (h *Handler) getOverviewRoles(ctx context.Context, request *http.Request, userID int64) (overviewRolesData, error) {
	if h.userHostClient == nil {
		return overviewRolesData{}, xerr.New(xerr.Unavailable, "user host service is not configured")
	}

	resp, err := h.userHostClient.GetUserRoleSummary(ctx, &userv1.GetUserRoleSummaryRequest{
		Meta:   authRequestMeta(request.WithContext(ctx), ""),
		UserId: userID,
	})
	if err != nil {
		return overviewRolesData{}, err
	}
	summary := resp.GetSummary()
	return overviewRolesData{
		IsHost:                 summary.GetIsHost(),
		IsAgency:               summary.GetIsAgency(),
		IsBD:                   summary.GetIsBd(),
		IsBDLeader:             summary.GetIsBdLeader(),
		IsCoinSeller:           summary.GetIsCoinSeller(),
		HostStatus:             summary.GetHostStatus(),
		AgencyID:               summary.GetAgencyId(),
		BDID:                   summary.GetBdId(),
		BDStatus:               summary.GetBdStatus(),
		CoinSellerStatus:       summary.GetCoinSellerStatus(),
		PendingRoleInvitations: summary.GetPendingRoleInvitations(),
	}, nil
}

func overviewWallet(resp *walletv1.GetWalletValueSummaryResponse, err error) overviewWalletData {
	if err != nil {
		return overviewWalletData{Unavailable: true}
	}
	summary := resp.GetSummary()
	return overviewWalletData{
		CoinAmount:  summary.GetCoinAmount(),
		UpdatedAtMS: summary.GetUpdatedAtMs(),
	}
}

func overviewVIP(resp *walletv1.GetMyVipResponse, err error) overviewVIPData {
	if err != nil {
		return overviewVIPData{Unavailable: true}
	}
	vip := resp.GetVip()
	return overviewVIPData{
		Level:       vip.GetLevel(),
		Name:        vip.GetName(),
		Active:      vip.GetActive(),
		StartedAtMS: vip.GetStartedAtMs(),
		ExpiresAtMS: vip.GetExpiresAtMs(),
	}
}

func overviewStats(resp *userv1.GetMyProfileStatsResponse, err error) overviewProfileStats {
	if err != nil {
		return overviewProfileStats{Unavailable: true}
	}
	return overviewStatsFromProto(resp.GetStats())
}

func overviewStatsFromProto(stats *userv1.UserProfileStats) overviewProfileStats {
	return overviewProfileStats{
		VisitorsCount:  stats.GetVisitorsCount(),
		FollowingCount: stats.GetFollowingCount(),
		FriendsCount:   stats.GetFriendsCount(),
		UpdatedAtMS:    stats.GetUpdatedAtMs(),
	}
}

func overviewEntries(roles overviewRolesData) []overviewEntryData {
	return []overviewEntryData{
		{Key: "store", Visible: true, Enabled: true, Route: "/store", IconKey: "store", Order: 10},
		{Key: "bag", Visible: true, Enabled: true, Route: "/bag", IconKey: "bag", Order: 20},
		{Key: "level", Visible: true, Enabled: true, Route: "/level", IconKey: "level", Order: 30},
		{Key: "task", Visible: true, Enabled: true, Route: "/task", IconKey: "task", Order: 40},
		{Key: "apply_host", Visible: !roles.IsHost, Enabled: true, Route: "/host/apply", IconKey: "host_apply", Order: 50},
		{Key: "host_center", Visible: roles.IsHost, Enabled: roles.IsHost, Route: "/host", IconKey: "host_center", Order: 60},
		{Key: "agency_center", Visible: roles.IsAgency, Enabled: roles.IsAgency, Route: "/agency", IconKey: "agency", Order: 70},
		{Key: "bd_center", Visible: roles.IsBD, Enabled: roles.IsBD, Route: "/bd", IconKey: "bd", Order: 80},
		{Key: "bd_leader_center", Visible: roles.IsBDLeader, Enabled: roles.IsBDLeader, Route: "/bd-leader", IconKey: "bd_leader", Order: 90},
		{Key: "coin_seller_center", Visible: roles.IsCoinSeller, Enabled: roles.IsCoinSeller, Route: "/coin-seller", IconKey: "coin_seller", Order: 100},
		{Key: "settings", Visible: true, Enabled: true, Route: "/settings", IconKey: "settings", Order: 110},
		{Key: "language", Visible: true, Enabled: true, Route: "/language", IconKey: "language", Order: 120},
	}
}
