package agent

import (
	"context"
	"bdqr-server/app/main/model"
	"bdqr-server/common/ctxdata"
	"bdqr-server/common/globalkey"
	"bdqr-server/common/xerr"
	"bdqr-server/pkg/lzkit/crypto"
	"sort"
	"strings"
	"time"

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

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

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

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

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

func (l *GetTeamListLogic) GetTeamList(req *types.GetTeamListReq) (resp *types.GetTeamListResp, err error) {
	userID, err := ctxdata.GetUidFromCtx(l.ctx)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err)
	}

	// 1. 获取代理信息
	agent, 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.DB_ERROR), "查询代理信息失败, %v", err)
	}

	// 2. 递归查询所有下级（直接+间接）
	allSubordinateIds := make(map[string]bool)
	directSubordinateIds := make(map[string]bool)

	// 递归函数：收集所有下级ID
	var collectSubordinates func(string) error
	collectSubordinates = func(parentId string) error {
		// 查询直接下级
		builder := l.svcCtx.AgentRelationModel.SelectBuilder().
			Where("parent_id = ? AND relation_type = ? AND del_state = ?", parentId, 1, globalkey.DelStateNo)
		relations, err := l.svcCtx.AgentRelationModel.FindAll(l.ctx, builder, "")
		if err != nil {
			return err
		}

		for _, relation := range relations {
			// 如果是第一层，标记为直接下级
			if parentId == agent.Id {
				directSubordinateIds[relation.ChildId] = true
			}
			// 添加到所有下级集合
			allSubordinateIds[relation.ChildId] = true
			// 递归查询下级的下级
			if err := collectSubordinates(relation.ChildId); err != nil {
				return err
			}
		}
		return nil
	}

	// 开始递归收集所有下级
	if err := collectSubordinates(agent.Id); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询下级关系失败, %v", err)
	}

	// 3. 如果没有下级，返回空数据
	if len(allSubordinateIds) == 0 {
		return &types.GetTeamListResp{
			Statistics: types.TeamStatistics{},
			Total:      0,
			List:       []types.TeamMemberItem{},
		}, nil
	}

	// 4. 将下级ID转换为切片用于查询
	subordinateIds := make([]string, 0, len(allSubordinateIds))
	for id := range allSubordinateIds {
		subordinateIds = append(subordinateIds, id)
	}

	// 5. 计算时间范围
	now := time.Now()
	todayStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())

	// 6. 统计顶部数据
	statistics := l.calculateTeamStatistics(agent.Id, subordinateIds, todayStart, monthStart)

	// 7. 查询所有下级代理信息（不进行手机号过滤，因为需要模糊搜索）
	builder := l.svcCtx.AgentModel.SelectBuilder().
		Where(squirrel.Eq{"id": subordinateIds}).
		Where("del_state = ?", globalkey.DelStateNo)

	allTeamMembers, err := l.svcCtx.AgentModel.FindAll(l.ctx, builder, "")
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询团队成员失败, %v", err)
	}

	// 8. 如果有手机号搜索条件，进行模糊匹配过滤（在内存中）
	var filteredMembers []*model.Agent
	searchMobile := strings.TrimSpace(req.Mobile)
	if searchMobile != "" {
		// 解密所有手机号并进行模糊匹配
		for _, member := range allTeamMembers {
			if member.Mobile != "" {
				decryptedMobile, err := crypto.DecryptMobile(member.Mobile, l.svcCtx.Config.Encrypt.SecretKey)
				if err == nil && strings.Contains(decryptedMobile, searchMobile) {
					filteredMembers = append(filteredMembers, member)
				}
			}
		}
	} else {
		// 没有搜索条件，使用所有成员
		filteredMembers = allTeamMembers
	}

	// 9. 按创建时间倒序排序
	sort.Slice(filteredMembers, func(i, j int) bool {
		return filteredMembers[i].CreateTime.After(filteredMembers[j].CreateTime)
	})

	// 10. 分页处理
	total := int64(len(filteredMembers))
	page := req.Page
	if page <= 0 {
		page = 1
	}
	pageSize := req.PageSize
	if pageSize <= 0 {
		pageSize = 20
	}
	offset := (page - 1) * pageSize

	// 计算分页范围
	start := int(offset)
	end := start + int(pageSize)
	if start > len(filteredMembers) {
		start = len(filteredMembers)
	}
	if end > len(filteredMembers) {
		end = len(filteredMembers)
	}

	var teamMembers []*model.Agent
	if start < end {
		teamMembers = filteredMembers[start:end]
	}

	// 11. 组装响应列表
	var list []types.TeamMemberItem
	for _, member := range teamMembers {
		memberItem := l.buildTeamMemberItem(agent.Id, member, directSubordinateIds, todayStart, monthStart)
		list = append(list, memberItem)
	}

	return &types.GetTeamListResp{
		Statistics: statistics,
		Total:      total,
		List:       list,
	}, nil
}

// calculateTeamStatistics 计算团队统计数据
// 注意：所有统计都基于 subordinateIds（下级ID列表），不包含自己的数据
func (l *GetTeamListLogic) calculateTeamStatistics(agentId string, subordinateIds []string, todayStart, monthStart time.Time) types.TeamStatistics {
	// 团队成员总数：只统计下级，不包括自己
	stats := types.TeamStatistics{
		TotalMembers: int64(len(subordinateIds)),
	}

	// 统计今日和本月新增成员（只统计下级，不包括自己）
	todayNewCount := int64(0)
	monthNewCount := int64(0)
	for _, id := range subordinateIds {
		member, err := l.svcCtx.AgentModel.FindOne(l.ctx, id)
		if err != nil {
			continue
		}
		if member.CreateTime.After(todayStart) {
			todayNewCount++
		}
		if member.CreateTime.After(monthStart) {
			monthNewCount++
		}
	}
	stats.TodayNewMembers = todayNewCount
	stats.MonthNewMembers = monthNewCount

	// 统计团队总查询量（仅统计有返佣给当前用户的订单，通过agent_rebate表去重统计order_id）
	if len(subordinateIds) > 0 {
		rebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
			Where("agent_id = ? AND del_state = ?", agentId, globalkey.DelStateNo).
			Where("source_agent_id != ?", agentId). // 明确排除自己
			Where(squirrel.Eq{"source_agent_id": subordinateIds})

		// 统计去重的订单数量
		totalQueries := l.countDistinctOrders(l.ctx, rebateBuilder)
		stats.TotalQueries = totalQueries

		// 今日推广量（仅统计有返佣的订单）
		todayRebateBuilder := rebateBuilder.Where("create_time >= ?", todayStart)
		todayPromotions := l.countDistinctOrders(l.ctx, todayRebateBuilder)
		stats.TodayPromotions = todayPromotions

		// 本月推广量（仅统计有返佣的订单）
		monthRebateBuilder := rebateBuilder.Where("create_time >= ?", monthStart)
		monthPromotions := l.countDistinctOrders(l.ctx, monthRebateBuilder)
		stats.MonthPromotions = monthPromotions
	}

	// 统计收益：只统计从下级获得的返佣（依靠团队得到的收益）
	// 返佣：从agent_rebate表统计（从下级获得的返佣）
	// agent_id = 当前代理ID（获得返佣的代理）
	// source_agent_id IN 下级ID列表（来源代理，即产生订单的下级代理）
	// 明确排除自己：source_agent_id != agentId（确保不统计自己的数据）
	if len(subordinateIds) > 0 {
		rebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
			Where("agent_id = ? AND del_state = ?", agentId, globalkey.DelStateNo).
			Where("source_agent_id != ?", agentId). // 明确排除自己
			Where(squirrel.Eq{"source_agent_id": subordinateIds})
		totalRebate, _ := l.svcCtx.AgentRebateModel.FindSum(l.ctx, rebateBuilder, "rebate_amount")
		todayRebate, _ := l.svcCtx.AgentRebateModel.FindSum(l.ctx, rebateBuilder.Where("create_time >= ?", todayStart), "rebate_amount")
		monthRebate, _ := l.svcCtx.AgentRebateModel.FindSum(l.ctx, rebateBuilder.Where("create_time >= ?", monthStart), "rebate_amount")

		stats.TotalEarnings = totalRebate
		stats.TodayEarnings = todayRebate
		stats.MonthEarnings = monthRebate
	}

	return stats
}

// countDistinctOrders 统计去重的订单数量（通过返佣记录）
func (l *GetTeamListLogic) countDistinctOrders(ctx context.Context, builder squirrel.SelectBuilder) int64 {
	// 查询所有返佣记录，在内存中去重订单ID
	rebates, err := l.svcCtx.AgentRebateModel.FindAll(ctx, builder, "")
	if err != nil {
		return 0
	}

	orderIdSet := make(map[string]bool)
	for _, rebate := range rebates {
		orderIdSet[rebate.OrderId] = true
	}

	return int64(len(orderIdSet))
}

// countDistinctOrdersForMember 统计单个成员的去重订单数量（通过返佣记录）
func (l *GetTeamListLogic) countDistinctOrdersForMember(ctx context.Context, builder squirrel.SelectBuilder) int64 {
	// 查询所有返佣记录，在内存中去重订单ID
	rebates, err := l.svcCtx.AgentRebateModel.FindAll(ctx, builder, "")
	if err != nil {
		return 0
	}

	orderIdSet := make(map[string]bool)
	for _, rebate := range rebates {
		orderIdSet[rebate.OrderId] = true
	}

	return int64(len(orderIdSet))
}

// buildTeamMemberItem 构建团队成员项
func (l *GetTeamListLogic) buildTeamMemberItem(agentId string, member *model.Agent, directSubordinateIds map[string]bool, todayStart, monthStart time.Time) types.TeamMemberItem {
	levelName := ""
	switch member.Level {
	case 1:
		levelName = "普通"
	case 2:
		levelName = "黄金"
	case 3:
		levelName = "钻石"
	}

	// 解密手机号
	mobile := ""
	if member.Mobile != "" {
		decrypted, err := crypto.DecryptMobile(member.Mobile, l.svcCtx.Config.Encrypt.SecretKey)
		if err == nil {
			mobile = decrypted
		}
	}

	// 统计查询量（仅统计有返佣给当前用户的订单，通过agent_rebate表去重统计order_id）
	rebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
		Where("agent_id = ? AND source_agent_id = ? AND del_state = ?", agentId, member.Id, globalkey.DelStateNo)
	totalQueries := l.countDistinctOrdersForMember(l.ctx, rebateBuilder)
	todayRebateBuilder := rebateBuilder.Where("create_time >= ?", todayStart)
	todayQueries := l.countDistinctOrdersForMember(l.ctx, todayRebateBuilder)
	monthRebateBuilder := rebateBuilder.Where("create_time >= ?", monthStart)
	monthQueries := l.countDistinctOrdersForMember(l.ctx, monthRebateBuilder)

	// 统计返佣给我的金额（从agent_rebate表，source_agent_id = member.Id, agent_id = agentId）
	totalRebateAmount, _ := l.svcCtx.AgentRebateModel.FindSum(l.ctx, rebateBuilder, "rebate_amount")
	todayRebateAmount, _ := l.svcCtx.AgentRebateModel.FindSum(l.ctx, rebateBuilder.Where("create_time >= ?", todayStart), "rebate_amount")

	// 统计邀请人数（从agent_relation表，parent_id = member.Id）
	inviteBuilder := l.svcCtx.AgentRelationModel.SelectBuilder().
		Where("parent_id = ? AND relation_type = ? AND del_state = ?", member.Id, 1, globalkey.DelStateNo)
	totalInvites, _ := l.svcCtx.AgentRelationModel.FindCount(l.ctx, inviteBuilder, "id")
	todayInvites, _ := l.svcCtx.AgentRelationModel.FindCount(l.ctx, inviteBuilder.Where("create_time >= ?", todayStart), "id")
	monthInvites, _ := l.svcCtx.AgentRelationModel.FindCount(l.ctx, inviteBuilder.Where("create_time >= ?", monthStart), "id")

	// 判断是否直接下级
	isDirect := directSubordinateIds[member.Id]

	return types.TeamMemberItem{
		AgentId:           member.Id,
		Level:             member.Level,
		LevelName:         levelName,
		Mobile:            mobile,
		CreateTime:        member.CreateTime.Format("2006-01-02 15:04:05"),
		TodayInvites:      todayInvites,
		MonthInvites:      monthInvites,
		TotalInvites:      totalInvites,
		TodayQueries:      todayQueries,
		MonthQueries:      monthQueries,
		TotalQueries:      totalQueries,
		TotalRebateAmount: totalRebateAmount,
		TodayRebateAmount: todayRebateAmount,
		IsDirect:          isDirect,
	}
}
