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

package order

import (
	"context"
	"strings"

	"juwan-backend/app/order/rpc/orderservice"
	"juwan-backend/app/player/rpc/playerservice"
	"juwan-backend/app/shop/rpc/shopservice"
	"juwan-backend/common/utils/contextj"

	"juwan-backend/app/order/api/internal/svc"
	"juwan-backend/app/order/api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

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

// 获取订单列表
func NewListOrdersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListOrdersLogic {
	return &ListOrdersLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *ListOrdersLogic) ListOrders(req *types.OrderListReq) (resp *types.OrderListResp, err error) {
	searchReq := &orderservice.SearchOrdersReq{
		Offset: req.Offset,
		Limit:  req.Limit,
	}
	if req.Status != "" {
		searchReq.Status = &req.Status
	}

	role := strings.ToLower(req.Role)
	if role != "" {
		uid, uidErr := contextj.UserIDFrom(l.ctx)
		if uidErr != nil {
			return nil, uidErr
		}
		switch role {
		case "consumer":
			searchReq.ConsumerId = &uid
		case "player":
			playerResp, playerErr := l.svcCtx.PlayerRpc.GetPlayerByUserId(l.ctx, &playerservice.SearchPlayersReq{UserId: &uid})
			if playerErr != nil {
				st, _ := status.FromError(playerErr)
				if st.Code() == codes.NotFound {
					return &types.OrderListResp{
						Items: []types.Order{},
						Meta: types.PageMeta{
							Total:  0,
							Offset: req.Offset,
							Limit:  req.Limit,
						},
					}, nil
				}
				return nil, playerErr
			}

			player := playerResp.GetPlayers()
			if player == nil {
				return &types.OrderListResp{
					Items: []types.Order{},
					Meta: types.PageMeta{
						Total:  0,
						Offset: req.Offset,
						Limit:  req.Limit,
					},
				}, nil
			}
			searchReq.PlayerId = &player.Id
		case "owner":
			shops, shopErr := l.svcCtx.ShopRpc.SearchShops(l.ctx, &shopservice.SearchShopsReq{
				Offset:  0,
				Limit:   100,
				OwnerId: uid,
			})
			if shopErr != nil {
				return nil, shopErr
			}

			items := make([]types.Order, 0)
			for _, shop := range shops.GetShops() {
				shopID := shop.GetId()
				q := &orderservice.SearchOrdersReq{
					Offset: req.Offset,
					Limit:  req.Limit,
					ShopId: &shopID,
				}
				if req.Status != "" {
					q.Status = &req.Status
				}
				out, rpcErr := l.svcCtx.OrderRpc.SearchOrders(l.ctx, q)
				if rpcErr != nil {
					return nil, rpcErr
				}
				for _, item := range out.GetOrders() {
					items = append(items, toAPIOrder(item))
				}
			}

			return &types.OrderListResp{
				Items: items,
				Meta: types.PageMeta{
					Total:  int64(len(items)),
					Offset: req.Offset,
					Limit:  req.Limit,
				},
			}, nil
		}
	}

	out, err := l.svcCtx.OrderRpc.SearchOrders(l.ctx, searchReq)
	if err != nil {
		return nil, err
	}

	items := make([]types.Order, 0, len(out.GetOrders()))
	for _, item := range out.GetOrders() {
		items = append(items, toAPIOrder(item))
	}

	return &types.OrderListResp{
		Items: items,
		Meta: types.PageMeta{
			Total:  int64(len(items)),
			Offset: req.Offset,
			Limit:  req.Limit,
		},
	}, nil
}
