package http

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

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

const (
	hostIdentityActiveStatus      = "active"
	hostIdentityAgencyInvitation  = "agency_invitation"
	hostIdentityAdminCreateAgency = "admin_create_agency"
	hostIdentityBDRole            = "bd"
	hostIdentityBDLeaderRole      = "bd_leader"
	hostIdentityCoinSellerAsset   = "COIN_SELLER_COIN"
)

type userHostIdentityData struct {
	IsHost       bool `json:"is_host"`
	IsAgent      bool `json:"is_agent"`
	IsBD         bool `json:"is_bd"`
	IsBDLeader   bool `json:"is_bd_leader"`
	IsCoinSeller bool `json:"is_coin_seller"`
}

// getMyHostIdentity 聚合当前用户在 host domain 中的 App 端身份开关。
func (h *Handler) getMyHostIdentity(writer http.ResponseWriter, request *http.Request) {
	if h.userHostClient == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}

	userID := auth.UserIDFromContext(request.Context())
	identity := userHostIdentityData{}

	hostResp, err := h.userHostClient.GetHostProfile(request.Context(), &userv1.GetHostProfileRequest{
		Meta:   authRequestMeta(request, ""),
		UserId: userID,
	})
	if err != nil {
		if xerr.ReasonFromGRPC(err) != xerr.NotFound {
			httpkit.WriteRPCError(writer, request, err)
			return
		}
	} else {
		applyHostIdentity(&identity, hostResp.GetHostProfile())
	}

	bdResp, err := h.userHostClient.GetBDProfile(request.Context(), &userv1.GetBDProfileRequest{
		Meta:   authRequestMeta(request, ""),
		UserId: userID,
	})
	if err != nil {
		if xerr.ReasonFromGRPC(err) != xerr.NotFound {
			httpkit.WriteRPCError(writer, request, err)
			return
		}
	} else {
		applyBDIdentity(&identity, bdResp.GetBdProfile())
	}

	coinSellerResp, err := h.userHostClient.GetCoinSellerProfile(request.Context(), &userv1.GetCoinSellerProfileRequest{
		Meta:   authRequestMeta(request, ""),
		UserId: userID,
	})
	if err != nil {
		if xerr.ReasonFromGRPC(err) != xerr.NotFound {
			httpkit.WriteRPCError(writer, request, err)
			return
		}
	} else {
		applyCoinSellerIdentity(&identity, coinSellerResp.GetCoinSellerProfile())
	}

	httpkit.WriteOK(writer, request, identity)
}

// getMyRoleSummary 返回我的页入口显隐所需的完整角色摘要。
func (h *Handler) getMyRoleSummary(writer http.ResponseWriter, request *http.Request) {
	if h.userHostClient == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	resp, err := h.userHostClient.GetUserRoleSummary(request.Context(), &userv1.GetUserRoleSummaryRequest{
		Meta:   authRequestMeta(request, ""),
		UserId: auth.UserIDFromContext(request.Context()),
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}
	summary := resp.GetSummary()
	httpkit.WriteOK(writer, request, 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(),
	})
}

func applyHostIdentity(identity *userHostIdentityData, profile *userv1.HostProfile) {
	if profile == nil || profile.GetStatus() != hostIdentityActiveStatus {
		return
	}

	identity.IsHost = true
	switch profile.GetSource() {
	case hostIdentityAgencyInvitation, hostIdentityAdminCreateAgency:
		identity.IsAgent = true
	}
}

func applyBDIdentity(identity *userHostIdentityData, profile *userv1.BDProfile) {
	if profile == nil || profile.GetStatus() != hostIdentityActiveStatus {
		return
	}

	switch profile.GetRole() {
	case hostIdentityBDLeaderRole:
		identity.IsBD = true
		identity.IsBDLeader = true
	case hostIdentityBDRole:
		identity.IsBD = true
	}
}

func applyCoinSellerIdentity(identity *userHostIdentityData, profile *userv1.CoinSellerProfile) {
	if profile == nil ||
		profile.GetStatus() != hostIdentityActiveStatus ||
		profile.GetMerchantAssetType() != hostIdentityCoinSellerAsset {
		return
	}

	identity.IsCoinSeller = true
}
