package agent

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

	"github.com/Masterminds/squirrel"
	"github.com/pkg/errors"

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

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

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

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

func (l *GetAgentRevenueInfoLogic) GetAgentRevenueInfo(req *types.GetAgentRevenueInfoReq) (resp *types.GetAgentRevenueInfoResp, err error) {
	claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理信息, %v", err)
	}
	userID := claims.UserId
	userType := claims.UserType
	if userType == model.UserTypeTemp {
		return &types.GetAgentRevenueInfoResp{
			Balance:       0,
			TotalEarnings: 0,
			FrozenBalance: 0,
			DirectPush: types.DirectPushReport{
				TotalCommission: 0,
				TotalReport:     0,
				Today:           types.TimeRangeReport{},
				Last7D:          types.TimeRangeReport{},
				Last30D:         types.TimeRangeReport{},
			},
			ActiveReward: types.ActiveReward{
				TotalReward: 0,
				Today:       types.ActiveRewardData{},
				Last7D:      types.ActiveRewardData{},
				Last30D:     types.ActiveRewardData{},
			},
		}, nil
	}
	agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
	}
	agentWalletModel, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agentModel.Id)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
	}
	resp = &types.GetAgentRevenueInfoResp{}
	resp.Balance = agentWalletModel.Balance
	resp.TotalEarnings = agentWalletModel.TotalEarnings
	resp.FrozenBalance = agentWalletModel.FrozenBalance

	// 直推报告统计
	//now := time.Now()
	//startTime := now.AddDate(0, 0, -30).Format("2006-01-02 15:04:05")
	//endTime := now.Format("2006-01-02 15:04:05")

	// 直推报告佣金
	agentCommissionModelBuild := l.svcCtx.AgentCommissionModel.SelectBuilder().
		Where(squirrel.Eq{"agent_id": agentModel.Id})
	//.Where(squirrel.Expr("create_time BETWEEN ? AND ?", startTime, endTime))

	agentCommissionsModel, err := l.svcCtx.AgentCommissionModel.FindAll(l.ctx, agentCommissionModelBuild, "")
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
	}
	// 筛选分类
	directPush, err := calculateDirectPushReport(agentCommissionsModel, nil)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
	}
	// 绑定到响应体
	resp.DirectPush = directPush

	// 活跃下级统计
	agentRewardsModelBuilder := l.svcCtx.AgentRewardsModel.SelectBuilder().Where("agent_id = ?", agentModel.Id)
	agentRewardsModel, err := l.svcCtx.AgentRewardsModel.FindAll(l.ctx, agentRewardsModelBuilder, "")
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
	}
	activeReward := calculateActiveReward(agentRewardsModel)
	resp.ActiveReward = activeReward

	return resp, nil
}

// 统计直推报告的独立函数
func calculateDirectPushReport(commissions []*model.AgentCommission, loc *time.Location) (types.DirectPushReport, error) {
	// 初始化报告结构
	report := types.DirectPushReport{
		Today:   types.TimeRangeReport{},
		Last7D:  types.TimeRangeReport{},
		Last30D: types.TimeRangeReport{},
	}

	// 获取当前中国时间
	now := time.Now()

	// 计算时间分界点
	todayStart := now.Add(-24 * time.Hour)
	last7dStart := now.AddDate(0, 0, -7)
	last30dStart := now.AddDate(0, 0, -30)

	// 遍历所有佣金记录
	for _, c := range commissions {
		// 转换时区
		createTime := c.CreateTime

		// 只统计非退款的佣金（status != 2）
		if c.Status == 2 {
			continue
		}

		// 统计总量
		report.TotalCommission += c.Amount
		report.TotalReport++

		// 近24小时（滚动周期）
		if createTime.After(todayStart) {
			report.Today.Commission += c.Amount
			report.Today.Report++
		}

		// 近7天（滚动周期）
		if createTime.After(last7dStart) {
			report.Last7D.Commission += c.Amount
			report.Last7D.Report++
		}

		// 近30天（滚动周期）
		if createTime.After(last30dStart) {
			report.Last30D.Commission += c.Amount
			report.Last30D.Report++
		}
	}

	return report, nil
}
func calculateActiveReward(rewards []*model.AgentRewards) types.ActiveReward {
	result := types.ActiveReward{
		Today:   types.ActiveRewardData{},
		Last7D:  types.ActiveRewardData{},
		Last30D: types.ActiveRewardData{},
	}

	now := time.Now()
	todayStart := now.Add(-24 * time.Hour) // 近24小时
	last7dStart := now.AddDate(0, 0, -7)   // 近7天
	last30dStart := now.AddDate(0, 0, -30) // 近30天

	for _, r := range rewards {
		createTime := r.CreateTime
		amount := r.Amount

		// 总奖励累加
		result.TotalReward += amount

		// 时间范围判断
		isToday := createTime.After(todayStart)
		isLast7d := createTime.After(last7dStart)
		isLast30d := createTime.After(last30dStart)

		// 类型分类统计
		switch r.Type {
		case model.AgentRewardsTypeDescendantWithdraw:
			addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "withdraw")

		case model.AgentRewardsTypeDescendantNewActive:
			addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "new_active")

		case model.AgentRewardsTypeDescendantUpgradeSvip, model.AgentRewardsTypeDescendantUpgradeVip:
			addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "upgrade")

		case model.AgentRewardsTypeDescendantPromotion:
			addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "promotion")
		}
	}
	return result
}

// 统一处理时间段累加
func addToPeriods(res *types.ActiveReward, amount float64, today, last7d, last30d bool, t string) {
	if today {
		addToData(&res.Today, amount, t)
	}
	if last7d {
		addToData(&res.Last7D, amount, t)
	}
	if last30d {
		addToData(&res.Last30D, amount, t)
	}
}

// 分类添加具体字段
func addToData(data *types.ActiveRewardData, amount float64, t string) {
	switch t {
	case "withdraw":
		data.SubWithdrawReward += amount
	case "new_active":
		data.NewActiveReward += amount
	case "upgrade":
		data.SubUpgradeReward += amount
	case "promotion":
		data.SubPromoteReward += amount
	}
}
