package userapi

import (
	"net/http"
	"strings"

	userv1 "hyapp.local/api/proto/user/v1"
	"hyapp/services/gateway-service/internal/auth"
	"hyapp/services/gateway-service/internal/transport/http/httpkit"
)

func (h *Handler) listMyRoleInvitations(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())
	status := strings.TrimSpace(request.URL.Query().Get("status"))
	if status == "" {
		status = "pending"
	}

	// 收件箱只按当前登录用户读取 target_user_id，前端不能传入任意用户 ID 枚举邀请消息。
	resp, err := h.userHostClient.ListRoleInvitations(request.Context(), &userv1.ListRoleInvitationsRequest{
		Meta:         httpkit.UserMeta(request, ""),
		TargetUserId: userID,
		Status:       status,
		PageSize:     int32(queryPageSize(request, 50)),
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}

	userIDs := make([]int64, 0, len(resp.GetInvitations())*2)
	for _, invitation := range resp.GetInvitations() {
		if invitation.GetInviterUserId() > 0 {
			userIDs = append(userIDs, invitation.GetInviterUserId())
		}
		if invitation.GetTargetUserId() > 0 {
			userIDs = append(userIDs, invitation.GetTargetUserId())
		}
	}
	users, err := h.userProfiles(request, userIDs)
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}

	items := make([]map[string]any, 0, len(resp.GetInvitations()))
	for _, invitation := range resp.GetInvitations() {
		items = append(items, map[string]any{
			"invitation": roleInvitationData(invitation),
			"inviter":    users[invitation.GetInviterUserId()],
			"target":     users[invitation.GetTargetUserId()],
		})
	}
	httpkit.WriteOK(writer, request, map[string]any{"items": items, "total": len(items)})
}

func (h *Handler) processMyRoleInvitation(writer http.ResponseWriter, request *http.Request) {
	if h.userHostClient == nil {
		httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
		return
	}
	invitationID, ok := httpkit.PositiveInt64PathValue(request, "invitation_id")
	if !ok {
		httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid invitation_id")
		return
	}
	var body map[string]any
	if !httpkit.Decode(writer, request, &body) {
		return
	}
	commandID := stringJSONValue(body["command_id"])
	action := strings.ToLower(strings.TrimSpace(stringJSONValue(body["action"])))
	if action == "agree" {
		action = "accept"
	} else if action == "refuse" {
		action = "reject"
	}
	if commandID == "" || (action != "accept" && action != "reject") {
		httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
		return
	}

	// 接受/拒绝入口只使用当前登录用户作为 actor_user_id；user-service 会再次校验他是否是邀请目标。
	resp, err := h.userHostClient.ProcessRoleInvitation(request.Context(), &userv1.ProcessRoleInvitationRequest{
		Meta:         httpkit.UserMeta(request, ""),
		CommandId:    commandID,
		ActorUserId:  auth.UserIDFromContext(request.Context()),
		InvitationId: invitationID,
		Action:       action,
		Reason:       strings.TrimSpace(stringJSONValue(body["reason"])),
	})
	if err != nil {
		httpkit.WriteRPCError(writer, request, err)
		return
	}

	httpkit.WriteOK(writer, request, map[string]any{
		"invitation":   roleInvitationData(resp.GetInvitation()),
		"host_profile": hostProfileData(resp.GetHostProfile()),
		"agency":       hostAgencyFromProto(resp.GetAgency()),
		"membership":   agencyMembershipData(resp.GetMembership()),
		"bd_profile":   bdLeaderProfileFromProto(resp.GetBdProfile()),
	})
}

func hostProfileData(profile *userv1.HostProfile) map[string]any {
	if profile == nil {
		return map[string]any{}
	}
	return map[string]any{
		"user_id":                      int64String(profile.GetUserId()),
		"status":                       profile.GetStatus(),
		"region_id":                    profile.GetRegionId(),
		"current_agency_id":            int64String(profile.GetCurrentAgencyId()),
		"current_membership_id":        int64String(profile.GetCurrentMembershipId()),
		"source":                       profile.GetSource(),
		"first_became_host_at_ms":      profile.GetFirstBecameHostAtMs(),
		"created_at_ms":                profile.GetCreatedAtMs(),
		"updated_at_ms":                profile.GetUpdatedAtMs(),
		"current_agency_owner_user_id": int64String(profile.GetCurrentAgencyOwnerUserId()),
	}
}
