package grpc

import (
	"context"

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

// CreateBDLeader 处理后台创建 BD Leader；权限和操作审计在 admin-server，user-service 只认事实约束。
func (s *Server) CreateBDLeader(ctx context.Context, req *userv1.CreateBDLeaderRequest) (*userv1.CreateBDLeaderResponse, error) {
	if s.hostSvc == nil {
		return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured"))
	}
	ctx = contextWithApp(ctx, req.GetMeta())
	profile, err := s.hostSvc.CreateBDLeader(ctx, hostservice.CreateBDLeaderInput{
		CommandID:    req.GetCommandId(),
		AdminUserID:  req.GetAdminUserId(),
		RegionID:     req.GetRegionId(),
		TargetUserID: req.GetTargetUserId(),
		Reason:       req.GetReason(),
		RequestID:    req.GetMeta().GetRequestId(),
	})
	if err != nil {
		return nil, xerr.ToGRPCError(err)
	}
	return &userv1.CreateBDLeaderResponse{BdProfile: toProtoBDProfile(profile)}, nil
}

// CreateBD 处理后台创建普通 BD，并绑定有效 BD Leader。
func (s *Server) CreateBD(ctx context.Context, req *userv1.CreateBDRequest) (*userv1.CreateBDResponse, error) {
	if s.hostSvc == nil {
		return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured"))
	}
	ctx = contextWithApp(ctx, req.GetMeta())
	profile, err := s.hostSvc.CreateBD(ctx, hostservice.CreateBDInput{
		CommandID:          req.GetCommandId(),
		AdminUserID:        req.GetAdminUserId(),
		TargetUserID:       req.GetTargetUserId(),
		ParentLeaderUserID: req.GetParentLeaderUserId(),
		Reason:             req.GetReason(),
		RequestID:          req.GetMeta().GetRequestId(),
	})
	if err != nil {
		return nil, xerr.ToGRPCError(err)
	}
	return &userv1.CreateBDResponse{BdProfile: toProtoBDProfile(profile)}, nil
}

// SetBDStatus 处理后台停用或恢复 BD/BD Leader。
func (s *Server) SetBDStatus(ctx context.Context, req *userv1.SetBDStatusRequest) (*userv1.SetBDStatusResponse, error) {
	if s.hostSvc == nil {
		return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured"))
	}
	ctx = contextWithApp(ctx, req.GetMeta())
	profile, err := s.hostSvc.SetBDStatus(ctx, hostservice.SetBDStatusInput{
		CommandID:    req.GetCommandId(),
		AdminUserID:  req.GetAdminUserId(),
		TargetUserID: req.GetTargetUserId(),
		Status:       req.GetStatus(),
		Reason:       req.GetReason(),
		RequestID:    req.GetMeta().GetRequestId(),
	})
	if err != nil {
		return nil, xerr.ToGRPCError(err)
	}
	return &userv1.SetBDStatusResponse{BdProfile: toProtoBDProfile(profile)}, nil
}

// CreateCoinSeller 处理后台创建币商身份；权限和操作审计在 admin-server。
func (s *Server) CreateCoinSeller(ctx context.Context, req *userv1.CreateCoinSellerRequest) (*userv1.CreateCoinSellerResponse, error) {
	if s.hostSvc == nil {
		return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured"))
	}
	ctx = contextWithApp(ctx, req.GetMeta())
	profile, err := s.hostSvc.CreateCoinSeller(ctx, hostservice.CreateCoinSellerInput{
		CommandID:    req.GetCommandId(),
		AdminUserID:  req.GetAdminUserId(),
		TargetUserID: req.GetTargetUserId(),
		Reason:       req.GetReason(),
		RequestID:    req.GetMeta().GetRequestId(),
	})
	if err != nil {
		return nil, xerr.ToGRPCError(err)
	}
	return &userv1.CreateCoinSellerResponse{CoinSellerProfile: toProtoCoinSellerProfile(profile)}, nil
}

// SetCoinSellerStatus 处理后台启用或停用币商身份。
func (s *Server) SetCoinSellerStatus(ctx context.Context, req *userv1.SetCoinSellerStatusRequest) (*userv1.SetCoinSellerStatusResponse, error) {
	if s.hostSvc == nil {
		return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured"))
	}
	ctx = contextWithApp(ctx, req.GetMeta())
	profile, err := s.hostSvc.SetCoinSellerStatus(ctx, hostservice.SetCoinSellerStatusInput{
		CommandID:    req.GetCommandId(),
		AdminUserID:  req.GetAdminUserId(),
		TargetUserID: req.GetTargetUserId(),
		Status:       req.GetStatus(),
		Reason:       req.GetReason(),
		RequestID:    req.GetMeta().GetRequestId(),
	})
	if err != nil {
		return nil, xerr.ToGRPCError(err)
	}
	return &userv1.SetCoinSellerStatusResponse{CoinSellerProfile: toProtoCoinSellerProfile(profile)}, nil
}

// CreateAgency 处理后台直接创建 Agency，并返回 owner host/membership 事实。
func (s *Server) CreateAgency(ctx context.Context, req *userv1.CreateAgencyRequest) (*userv1.CreateAgencyResponse, error) {
	if s.hostSvc == nil {
		return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured"))
	}
	ctx = contextWithApp(ctx, req.GetMeta())
	result, err := s.hostSvc.CreateAgency(ctx, hostservice.CreateAgencyInput{
		CommandID:      req.GetCommandId(),
		AdminUserID:    req.GetAdminUserId(),
		OwnerUserID:    req.GetOwnerUserId(),
		ParentBDUserID: req.GetParentBdUserId(),
		Name:           req.GetName(),
		JoinEnabled:    req.GetJoinEnabled(),
		MaxHosts:       req.GetMaxHosts(),
		Reason:         req.GetReason(),
		RequestID:      req.GetMeta().GetRequestId(),
	})
	if err != nil {
		return nil, xerr.ToGRPCError(err)
	}
	return &userv1.CreateAgencyResponse{
		Agency:      toProtoAgency(result.Agency),
		HostProfile: toProtoHostProfile(result.HostProfile),
		Membership:  toProtoAgencyMembership(result.Membership),
	}, nil
}

// CloseAgency 处理后台关闭 Agency；关闭后 App 搜索不会再返回该 Agency。
func (s *Server) CloseAgency(ctx context.Context, req *userv1.CloseAgencyRequest) (*userv1.CloseAgencyResponse, error) {
	if s.hostSvc == nil {
		return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured"))
	}
	ctx = contextWithApp(ctx, req.GetMeta())
	agency, err := s.hostSvc.CloseAgency(ctx, hostservice.CloseAgencyInput{
		CommandID:   req.GetCommandId(),
		AdminUserID: req.GetAdminUserId(),
		AgencyID:    req.GetAgencyId(),
		Reason:      req.GetReason(),
		RequestID:   req.GetMeta().GetRequestId(),
	})
	if err != nil {
		return nil, xerr.ToGRPCError(err)
	}
	return &userv1.CloseAgencyResponse{Agency: toProtoAgency(agency)}, nil
}

// SetAgencyJoinEnabled 处理后台设置 Agency 入会开关。
func (s *Server) SetAgencyJoinEnabled(ctx context.Context, req *userv1.SetAgencyJoinEnabledRequest) (*userv1.SetAgencyJoinEnabledResponse, error) {
	if s.hostSvc == nil {
		return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "host service is not configured"))
	}
	ctx = contextWithApp(ctx, req.GetMeta())
	agency, err := s.hostSvc.SetAgencyJoinEnabled(ctx, hostservice.SetAgencyJoinEnabledInput{
		CommandID:   req.GetCommandId(),
		AdminUserID: req.GetAdminUserId(),
		AgencyID:    req.GetAgencyId(),
		JoinEnabled: req.GetJoinEnabled(),
		Reason:      req.GetReason(),
		RequestID:   req.GetMeta().GetRequestId(),
	})
	if err != nil {
		return nil, xerr.ToGRPCError(err)
	}
	return &userv1.SetAgencyJoinEnabledResponse{Agency: toProtoAgency(agency)}, nil
}
