package admin_user

import (
	"context"
	"errors"
	"sync"

	"qnc-server/app/main/api/internal/svc"
	"qnc-server/app/main/api/internal/types"
	"qnc-server/app/main/model"

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

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

func NewAdminGetUserDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminGetUserDetailLogic {
	return &AdminGetUserDetailLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *AdminGetUserDetailLogic) AdminGetUserDetail(req *types.AdminGetUserDetailReq) (resp *types.AdminGetUserDetailResp, err error) {
	// 使用MapReduceVoid并发获取用户信息和角色ID
	var user *model.AdminUser
	var roleIds []string
	var mutex sync.Mutex
	var wg sync.WaitGroup

	mr.MapReduceVoid(func(source chan<- interface{}) {
		source <- 1 // 获取用户信息
		source <- 2 // 获取角色ID
	}, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) {
		taskType := item.(int)
		wg.Add(1)
		defer wg.Done()

		if taskType == 1 {
			result, err := l.svcCtx.AdminUserModel.FindOne(l.ctx, req.Id)
			if err != nil {
				cancel(err)
				return
			}
			mutex.Lock()
			user = result
			mutex.Unlock()
		} else if taskType == 2 {
			builder := l.svcCtx.AdminUserRoleModel.SelectBuilder().
				Where("user_id = ?", req.Id)
			roles, err := l.svcCtx.AdminUserRoleModel.FindAll(l.ctx, builder, "id ASC")
			if err != nil {
				cancel(err)
				return
			}
			mutex.Lock()
			roleIds = lo.Map(roles, func(item *model.AdminUserRole, _ int) string {
				return item.RoleId
			})
			mutex.Unlock()
		}
	}, func(pipe <-chan interface{}, cancel func(error)) {
		// 不需要处理pipe中的数据
	})

	wg.Wait()

	if user == nil {
		return nil, errors.New("用户不存在")
	}

	return &types.AdminGetUserDetailResp{
		Id:         user.Id,
		Username:   user.Username,
		RealName:   user.RealName,
		Status:     user.Status,
		CreateTime: user.CreateTime.Format("2006-01-02 15:04:05"),
		UpdateTime: user.UpdateTime.Format("2006-01-02 15:04:05"),
		RoleIds:    roleIds,
	}, nil
}
