package agent

import (
	"context"
	"ycc-server/app/main/model"
	"ycc-server/common/ctxdata"
	"ycc-server/common/xerr"

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

	"ycc-server/app/main/api/internal/svc"
	"ycc-server/app/main/api/internal/types"

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

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

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

type AgentProductConfigResp struct {
}

func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentProductConfigResp, err error) {
	userID, err := ctxdata.GetUidFromCtx(l.ctx)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取推广项目配置失败, %v", err)
	}
	agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
	if err != nil {
		if errors.Is(err, model.ErrNotFound) {
			return nil, errors.Wrapf(xerr.NewErrMsg("您不是代理"), "")
		}
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取推广项目配置失败, %v", err)
	}
	// 1. 查询推广项目配置数据
	builder := l.svcCtx.AgentProductConfigModel.SelectBuilder()
	agentProductConfigModelAll, err := l.svcCtx.AgentProductConfigModel.FindAll(l.ctx, builder, "")
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取推广项目配置失败, %v", err)
	}

	// 用于存放最终组装好的响应数据
	var respList []types.AgentProductConfig

	// 2. 使用 mr.MapReduceVoid 并行处理每个推广项目配置项
	mrMapErr := mr.MapReduceVoid(
		// source 函数：遍历所有推广项目配置，将每个配置项发送到 channel 中
		func(source chan<- interface{}) {
			for _, config := range agentProductConfigModelAll {
				source <- config
			}
		},
		// map 函数：处理每个推广项目配置项，根据 ProductId 查询会员用户配置，并组装响应数据
		func(item interface{}, writer mr.Writer[*types.AgentProductConfig], cancel func(error)) {
			// 将 item 转换为推广项目配置模型
			config := item.(*model.AgentProductConfig)
			var agentProductConfig types.AgentProductConfig
			// 配置平台成本价和定价成本
			agentProductConfigModel, findAgentProductConfigErr := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, config.ProductId)
			if findAgentProductConfigErr != nil {
				cancel(findAgentProductConfigErr)
				return
			}
			agentProductConfig.ProductID = config.ProductId
			agentProductConfig.CostPrice = agentProductConfigModel.CostPrice
			agentProductConfig.PriceRangeMin = agentProductConfigModel.PriceRangeMin
			agentProductConfig.PriceRangeMax = agentProductConfigModel.PriceRangeMax
			agentProductConfig.PPricingStandard = agentProductConfigModel.PricingStandard
			agentProductConfig.POverpricingRatio = agentProductConfigModel.OverpricingRatio

			// 看推广人是否有上级，上级是否有这个配置权限，上级是否有相关配置
			agentClosureModel, findAgentClosureErr := l.svcCtx.AgentClosureModel.FindOneByDescendantIdDepth(l.ctx, agentModel.Id, 1)
			if findAgentClosureErr != nil && !errors.Is(findAgentClosureErr, model.ErrNotFound) {
				cancel(findAgentClosureErr)
				return
			}
			if agentClosureModel != nil {
				ancestorAgentModel, findAncestorAgentErr := l.svcCtx.AgentModel.FindOne(l.ctx, agentClosureModel.AncestorId)
				if findAncestorAgentErr != nil {
					cancel(findAncestorAgentErr)
					return
				}
				if ancestorAgentModel.LevelName == "" {
					ancestorAgentModel.LevelName = model.AgentLeveNameNormal
				}
				agentMembershipConfigModel, findAgentMembershipErr := l.svcCtx.AgentMembershipConfigModel.FindOneByLevelName(l.ctx, ancestorAgentModel.LevelName)
				if findAgentMembershipErr != nil {
					cancel(findAgentMembershipErr)
					return
				}
				// 是否有提成本价
				if agentMembershipConfigModel.PriceIncreaseAmount.Valid {
					// 根据产品ID查询会员用户配置数据
					membershipUserConfigModel, membershipConfigErr := l.svcCtx.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(l.ctx, agentClosureModel.AncestorId, config.ProductId)
					if membershipConfigErr != nil {
						if errors.Is(membershipConfigErr, model.ErrNotFound) {
							writer.Write(&agentProductConfig)
							return
						}
						cancel(membershipConfigErr)
						return
					}
					agentProductConfig.CostPrice += membershipUserConfigModel.PriceIncreaseAmount
					agentProductConfig.PriceRangeMin += membershipUserConfigModel.PriceIncreaseAmount
					agentProductConfig.APricingStandard = membershipUserConfigModel.PriceRangeFrom
					agentProductConfig.APricingEnd = membershipUserConfigModel.PriceRangeTo
					agentProductConfig.AOverpricingRatio = membershipUserConfigModel.PriceRatio
				}
			}
			writer.Write(&agentProductConfig)

		},
		// reduce 函数：收集 map 阶段写入的响应数据，并汇总到 respList 中
		func(pipe <-chan *types.AgentProductConfig, cancel func(error)) {
			for item := range pipe {
				respList = append(respList, *item)
			}
		},
	)
	if mrMapErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取推广项目配置失败, %+v", mrMapErr)
	}

	// 3. 组装最终响应返回
	return &types.AgentProductConfigResp{
		AgentProductConfig: respList,
	}, nil
}
