package admin_promotion

import (
	"context"
	"fmt"

	"ycc-server/app/main/api/internal/svc"
	"ycc-server/app/main/api/internal/types"
	"ycc-server/app/main/model"
	"ycc-server/common/ctxdata"
	"ycc-server/common/xerr"

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

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

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

func (l *GetPromotionLinkListLogic) GetPromotionLinkList(req *types.GetPromotionLinkListReq) (resp *types.GetPromotionLinkListResp, err error) {
	// 获取当前用户ID
	adminUserId, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
	if getUidErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取当前用户ID失败, %+v", getUidErr)
	}

	// 构建查询条件
	builder := l.svcCtx.AdminPromotionLinkModel.SelectBuilder()
	builder = builder.Where("admin_user_id = ?", adminUserId)
	if req.Name != "" {
		builder = builder.Where("name LIKE ?", "%"+req.Name+"%")
	}
	if req.Url != "" {
		builder = builder.Where("url LIKE ?", "%"+req.Url+"%")
	}

	// 获取列表和总数
	links, total, err := l.svcCtx.AdminPromotionLinkModel.FindPageListByPageWithTotal(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
	if err != nil {
		return nil, errors.Wrapf(err, "获取推广链接列表失败, %+v", err)
	}

	// 使用MapReduce并发获取统计数据
	items := make([]types.PromotionLinkItem, len(links))
	err = mr.MapReduceVoid(func(source chan<- interface{}) {
		for _, link := range links {
			source <- link
		}
	}, func(item interface{}, writer mr.Writer[types.PromotionLinkItem], cancel func(error)) {
		link := item.(*model.AdminPromotionLink)
		// 获取总统计
		totalStats, err := l.svcCtx.AdminPromotionLinkStatsTotalModel.FindOneByLinkId(l.ctx, link.Id)
		if err != nil && !errors.Is(err, model.ErrNotFound) {
			cancel(errors.Wrapf(err, "获取总统计失败, linkId: %d, %+v", link.Id, err))
			return
		}
		writer.Write(types.PromotionLinkItem{
			Id:         link.Id,
			Name:       link.Name,
			Url:        link.Url,
			ClickCount: totalStats.ClickCount,
			PayCount:   totalStats.PayCount,
			PayAmount:  fmt.Sprintf("%.2f", totalStats.PayAmount),
			CreateTime: link.CreateTime.Format("2006-01-02 15:04:05"),
			LastClickTime: func() string {
				if totalStats.LastClickTime.Valid {
					return totalStats.LastClickTime.Time.Format("2006-01-02 15:04:05")
				}
				return ""
			}(),
			LastPayTime: func() string {
				if totalStats.LastPayTime.Valid {
					return totalStats.LastPayTime.Time.Format("2006-01-02 15:04:05")
				}
				return ""
			}(),
		})
	}, func(pipe <-chan types.PromotionLinkItem, cancel func(error)) {
		for i := 0; i < len(links); i++ {
			item := <-pipe
			items[i] = item
		}
	})
	if err != nil {
		return nil, errors.Wrapf(err, "获取推广链接统计数据失败, %+v", err)
	}

	return &types.GetPromotionLinkListResp{
		Total: total,
		Items: items,
	}, nil
}
