package admin_query

import (
	"context"
	"tydata-server/app/main/api/internal/svc"
	"tydata-server/app/main/api/internal/types"
	"tydata-server/app/main/model"
	"tydata-server/common/globalkey"
	"tydata-server/common/xerr"
	"sync"

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

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

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

func (l *AdminGetQueryCleanupDetailListLogic) AdminGetQueryCleanupDetailList(req *types.AdminGetQueryCleanupDetailListReq) (resp *types.AdminGetQueryCleanupDetailListResp, err error) {
	// 1. 验证清理日志是否存在
	_, err = l.svcCtx.QueryCleanupLogModel.FindOne(l.ctx, req.LogId)
	if err != nil {
		if err == model.ErrNotFound {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "清理日志不存在, log_id: %d", req.LogId)
		}
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询清理日志失败, log_id: %d, err: %v", req.LogId, err)
	}

	// 2. 构建查询条件
	builder := l.svcCtx.QueryCleanupDetailModel.SelectBuilder().
		Where("cleanup_log_id = ?", req.LogId).
		Where("del_state = ?", globalkey.DelStateNo)

	// 3. 并发获取总数和列表
	var total int64
	var details []*model.QueryCleanupDetail
	err = mr.Finish(func() error {
		var err error
		total, err = l.svcCtx.QueryCleanupDetailModel.FindCount(l.ctx, builder, "id")
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询清理详情总数失败 err: %v", err)
		}
		return nil
	}, func() error {
		var err error
		details, err = l.svcCtx.QueryCleanupDetailModel.FindPageListByPage(l.ctx, builder, req.Page, req.PageSize, "id DESC")
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询清理详情列表失败 err: %v", err)
		}
		return nil
	})
	if err != nil {
		return nil, err
	}

	// 4. 获取所有产品ID
	productIds := make([]int64, 0, len(details))
	for _, detail := range details {
		productIds = append(productIds, detail.ProductId)
	}

	// 5. 并发获取产品信息
	productMap := make(map[int64]string)
	var mu sync.Mutex
	err = mr.MapReduceVoid(func(source chan<- interface{}) {
		for _, productId := range productIds {
			source <- productId
		}
	}, func(item interface{}, writer mr.Writer[struct{}], cancel func(error)) {
		productId := item.(int64)
		product, err := l.svcCtx.ProductModel.FindOne(l.ctx, productId)
		if err != nil && !errors.Is(err, model.ErrNotFound) {
			cancel(errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询产品信息失败, product_id: %d, err: %v", productId, err))
			return
		}
		mu.Lock()
		if product != nil {
			productMap[productId] = product.ProductName
		} else {
			productMap[productId] = "" // 产品不存在时设置为空字符串
		}
		mu.Unlock()
		writer.Write(struct{}{})
	}, func(pipe <-chan struct{}, cancel func(error)) {
		for range pipe {
		}
	})
	if err != nil {
		return nil, err
	}

	// 6. 构建响应
	resp = &types.AdminGetQueryCleanupDetailListResp{
		Total: total,
		Items: make([]types.QueryCleanupDetailItem, 0, len(details)),
	}

	for _, detail := range details {
		item := types.QueryCleanupDetailItem{
			Id:            detail.Id,
			CleanupLogId:  detail.CleanupLogId,
			QueryId:       detail.QueryId,
			OrderId:       detail.OrderId,
			UserId:        detail.UserId,
			ProductName:   productMap[detail.ProductId],
			QueryState:    detail.QueryState,
			CreateTimeOld: detail.CreateTimeOld.Format("2006-01-02 15:04:05"),
			CreateTime:    detail.CreateTime.Format("2006-01-02 15:04:05"),
		}
		resp.Items = append(resp.Items, item)
	}

	return resp, nil
}
