// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2

package player

import (
	"context"
	"encoding/json"
	"strconv"
	"time"

	"juwan-backend/app/player/api/internal/svc"
	"juwan-backend/app/player/api/internal/types"
	"juwan-backend/app/player/rpc/pb"
	"juwan-backend/app/users/rpc/usercenter"

	"github.com/zeromicro/go-zero/core/logx"
)

type ListPlayersLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// 获取打手列表
func NewListPlayersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListPlayersLogic {
	return &ListPlayersLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *ListPlayersLogic) ListPlayers(req *types.PlayerListReq) (resp *types.PlayerListResp, err error) {
	p, err := l.svcCtx.PlayerRpc.SearchPlayers(l.ctx, &pb.SearchPlayersReq{
		Offset: &req.Offset,
		Limit:  &req.Limit,
		Gender: &req.Gender,
	})
	if err != nil {
		return nil, err
	}

	if len(p.Players) == 0 {
		return &types.PlayerListResp{Items: []types.PlayerProfile{}}, nil
	}

	userIds := make([]int64, 0, len(p.Players))
	for _, v := range p.Players {
		userIds = append(userIds, v.UserId)
	}
	usersResp, err := l.svcCtx.UserRpc.GetUsersByIds(l.ctx, &usercenter.GetUsersByIdsReq{Ids: userIds})
	if err != nil {
		return nil, err
	}
	userMap := make(map[int64]*usercenter.Users, len(usersResp.Users))
	for _, u := range usersResp.Users {
		userMap[u.Id] = u
	}

	list := make([]types.PlayerProfile, 0, len(p.Players))
	for _, v := range p.Players {
		profile := types.PlayerProfile{
			Id:          v.Id,
			Rating:      v.Rating,
			TotalOrders: v.TotalOrders,
			Status:      v.Status,
			Gender:      v.Gender,
			Services:    []types.PlayerService{},
			Tags:        append([]string{}, v.Tags...),
		}

		games := make([]string, 0, len(v.Games))
		for _, gameID := range v.Games {
			games = append(games, strconv.FormatInt(gameID, 10))
		}
		profile.Games = games

		if v.ShopId != 0 {
			profile.ShopId = strconv.FormatInt(v.ShopId, 10)
		}

		if u, ok := userMap[v.UserId]; ok {
			verificationStatus := map[string]string{}
			if u.VerificationStatus != "" {
				_ = json.Unmarshal([]byte(u.VerificationStatus), &verificationStatus)
			}
			profile.User = types.UserProfile{
				Id:                 strconv.FormatInt(u.Id, 10),
				Username:           u.Username,
				Nickname:           u.Nickname,
				Avatar:             u.Avatar,
				Role:               u.CurrentRole,
				VerifiedRoles:      append([]string{}, u.VerifiedRoles...),
				VerificationStatus: verificationStatus,
				Phone:              u.Phone,
				Bio:                u.Bio,
				CreatedAt:          time.Unix(u.CreatedAt, 0).Format(time.DateTime),
			}
		}

		svcResp, svcErr := l.svcCtx.PlayerRpc.SearchPlayerServices(l.ctx, &pb.SearchPlayerServicesReq{
			PlayerId: v.Id,
			Limit:    100,
		})
		if svcErr != nil {
			logx.Errorf("ListPlayers SearchPlayerServices player=%d err: %v", v.Id, svcErr)
		} else {
			for _, s := range svcResp.PlayerServices {
				profile.Services = append(profile.Services, types.PlayerService{
					Id:           s.Id,
					PlayerId:     s.PlayerId,
					GameId:       s.GameId,
					Title:        s.Title,
					Description:  s.Description,
					Price:        s.Price,
					Unit:         s.Unit,
					RankRange:    s.RankRange,
					Availability: s.Availability,
				})
			}
		}

		list = append(list, profile)
	}

	return &types.PlayerListResp{Items: list}, nil
}
