package agent

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

	"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 GetSubordinateContributionDetailLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

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

func (l *GetSubordinateContributionDetailLogic) GetSubordinateContributionDetail(req *types.GetSubordinateContributionDetailReq) (resp *types.GetSubordinateContributionDetailResp, 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. 验证下级代理是否存在，并且确实是当前代理的下级（直接或间接）
	subordinate, err := l.svcCtx.AgentModel.FindOne(l.ctx, req.SubordinateId)
	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)
	}

	// 3. 验证下级关系（递归检查是否是下级）
	isSubordinate := l.isSubordinate(agent.Id, req.SubordinateId)
	if !isSubordinate {
		return nil, errors.Wrapf(xerr.NewErrMsg("该代理不是您的下级"), "")
	}

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

	// 5. 获取等级名称
	levelName := ""
	switch subordinate.Level {
	case 1:
		levelName = "普通"
	case 2:
		levelName = "黄金"
	case 3:
		levelName = "钻石"
	}

	// 6. 计算时间范围
	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())

	// 7. 统计订单数据（仅统计有返佣给当前用户的订单）
	// 通过 agent_rebate 表统计 DISTINCT order_id
	rebateBaseBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
		Where("agent_id = ? AND source_agent_id = ? AND del_state = ?", agent.Id, req.SubordinateId, globalkey.DelStateNo)

	// 总订单量（去重订单ID）
	totalOrders := l.countDistinctOrders(l.ctx, rebateBaseBuilder)

	// 今日订单量
	todayRebateBuilder := rebateBaseBuilder.Where("create_time >= ?", todayStart)
	todayOrders := l.countDistinctOrders(l.ctx, todayRebateBuilder)

	// 月订单量
	monthRebateBuilder := rebateBaseBuilder.Where("create_time >= ?", monthStart)
	monthOrders := l.countDistinctOrders(l.ctx, monthRebateBuilder)

	// 8. 统计返佣金额
	totalRebateAmount, _ := l.svcCtx.AgentRebateModel.FindSum(l.ctx, rebateBaseBuilder, "rebate_amount")
	todayRebateAmount, _ := l.svcCtx.AgentRebateModel.FindSum(l.ctx, todayRebateBuilder, "rebate_amount")
	monthRebateAmount, _ := l.svcCtx.AgentRebateModel.FindSum(l.ctx, monthRebateBuilder, "rebate_amount")

	// 9. 统计邀请数据
	inviteBaseBuilder := l.svcCtx.AgentRelationModel.SelectBuilder().
		Where("parent_id = ? AND relation_type = ? AND del_state = ?", req.SubordinateId, 1, globalkey.DelStateNo)
	totalInvites, _ := l.svcCtx.AgentRelationModel.FindCount(l.ctx, inviteBaseBuilder, "id")

	todayInviteBuilder := inviteBaseBuilder.Where("create_time >= ?", todayStart)
	todayInvites, _ := l.svcCtx.AgentRelationModel.FindCount(l.ctx, todayInviteBuilder, "id")

	monthInviteBuilder := inviteBaseBuilder.Where("create_time >= ?", monthStart)
	monthInvites, _ := l.svcCtx.AgentRelationModel.FindCount(l.ctx, monthInviteBuilder, "id")

	// 10. 分页查询订单列表或邀请列表
	page := req.Page
	if page <= 0 {
		page = 1
	}
	pageSize := req.PageSize
	if pageSize <= 0 {
		pageSize = 20
	}

	var orderList []types.OrderItem
	var inviteList []types.InviteItem
	var orderListTotal int64
	var inviteListTotal int64

	tabType := req.TabType
	if tabType == "" {
		tabType = "order" // 默认显示订单列表
	}

	if tabType == "order" {
		// 查询订单列表（仅显示有返佣的订单）
		orderList, orderListTotal, err = l.getOrderList(l.ctx, agent.Id, req.SubordinateId, page, pageSize)
		if err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询订单列表失败, %v", err)
		}
	} else if tabType == "invite" {
		// 查询邀请列表
		inviteList, inviteListTotal, err = l.getInviteList(l.ctx, req.SubordinateId, page, pageSize)
		if err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询邀请列表失败, %v", err)
		}
	}

	// 11. 组装响应
	resp = &types.GetSubordinateContributionDetailResp{
		Mobile:     mobile,
		LevelName:  levelName,
		CreateTime: subordinate.CreateTime.Format("2006-01-02 15:04:05"),
		OrderStats: types.OrderStatistics{
			TotalOrders: totalOrders,
			MonthOrders: monthOrders,
			TodayOrders: todayOrders,
		},
		RebateStats: types.RebateStatistics{
			TotalRebateAmount: totalRebateAmount,
			TodayRebateAmount: todayRebateAmount,
			MonthRebateAmount: monthRebateAmount,
		},
		InviteStats: types.InviteStatistics{
			TotalInvites: totalInvites,
			TodayInvites: todayInvites,
			MonthInvites: monthInvites,
		},
		OrderList:       orderList,
		InviteList:      inviteList,
		OrderListTotal:  orderListTotal,
		InviteListTotal: inviteListTotal,
	}

	return resp, nil
}

// isSubordinate 递归检查 targetId 是否是 parentId 的下级（直接或间接）
func (l *GetSubordinateContributionDetailLogic) isSubordinate(parentId, targetId string) bool {
	// 查询直接下级
	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 false
	}

	for _, relation := range relations {
		// 如果是直接下级，返回 true
		if relation.ChildId == targetId {
			return true
		}
		// 递归检查间接下级
		if l.isSubordinate(relation.ChildId, targetId) {
			return true
		}
	}

	return false
}

// countDistinctOrders 统计去重的订单数量（通过返佣记录）
func (l *GetSubordinateContributionDetailLogic) 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))
}

// getOrderList 获取订单列表（仅显示有返佣的订单）
func (l *GetSubordinateContributionDetailLogic) getOrderList(ctx context.Context, agentId, subordinateId string, page, pageSize int64) ([]types.OrderItem, int64, error) {
	// 1. 查询所有返佣记录
	rebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
		Where("agent_id = ? AND source_agent_id = ? AND del_state = ?", agentId, subordinateId, globalkey.DelStateNo).
		OrderBy("create_time DESC")

	// 查询总数（去重订单ID）
	totalBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
		Where("agent_id = ? AND source_agent_id = ? AND del_state = ?", agentId, subordinateId, globalkey.DelStateNo)
	total := l.countDistinctOrders(ctx, totalBuilder)

	// 查询所有返佣记录
	allRebates, err := l.svcCtx.AgentRebateModel.FindAll(ctx, rebateBuilder, "")
	if err != nil {
		return nil, 0, err
	}

	if len(allRebates) == 0 {
		return []types.OrderItem{}, total, nil
	}

	// 2. 在内存中去重订单ID，并按创建时间排序
	type OrderRebateInfo struct {
		OrderId      string
		RebateId     string
		ProductId    string
		RebateAmount float64
		CreateTime   time.Time
	}

	orderMap := make(map[string]*OrderRebateInfo) // orderId -> 最新的返佣信息
	for _, rebate := range allRebates {
		if existing, ok := orderMap[rebate.OrderId]; ok {
			// 如果已存在，保留创建时间最新的
			if rebate.CreateTime.After(existing.CreateTime) {
				orderMap[rebate.OrderId] = &OrderRebateInfo{
					OrderId:      rebate.OrderId,
					RebateId:     rebate.Id,
					ProductId:    rebate.ProductId,
					RebateAmount: rebate.RebateAmount,
					CreateTime:   rebate.CreateTime,
				}
			}
		} else {
			orderMap[rebate.OrderId] = &OrderRebateInfo{
				OrderId:      rebate.OrderId,
				RebateId:     rebate.Id,
				ProductId:    rebate.ProductId,
				RebateAmount: rebate.RebateAmount,
				CreateTime:   rebate.CreateTime,
			}
		}
	}

	// 3. 转换为切片并按时间排序
	orderList := make([]*OrderRebateInfo, 0, len(orderMap))
	for _, info := range orderMap {
		orderList = append(orderList, info)
	}

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

	// 4. 分页
	offset := (page - 1) * pageSize
	end := offset + pageSize
	if end > int64(len(orderList)) {
		end = int64(len(orderList))
	}
	if offset >= int64(len(orderList)) {
		return []types.OrderItem{}, total, nil
	}

	pagedOrderList := orderList[offset:end]

	// 5. 组装订单列表
	var resultList []types.OrderItem
	productCache := make(map[string]string) // 产品ID -> 产品名称缓存

	for _, orderInfo := range pagedOrderList {
		// 查询订单信息
		order, err := l.svcCtx.OrderModel.FindOne(ctx, orderInfo.OrderId)
		if err != nil {
			continue
		}

		// 查询agent_order信息（用于获取订单金额）
		agentOrder, err := l.svcCtx.AgentOrderModel.FindOneByOrderId(ctx, orderInfo.OrderId)
		if err != nil {
			continue
		}

		// 查询产品名称（使用缓存）
		productName := ""
		if name, ok := productCache[orderInfo.ProductId]; ok {
			productName = name
		} else {
			product, err := l.svcCtx.ProductModel.FindOne(ctx, orderInfo.ProductId)
			if err == nil {
				productName = product.ProductName
				productCache[orderInfo.ProductId] = productName
			}
		}

		resultList = append(resultList, types.OrderItem{
			OrderNo:      order.OrderNo,
			ProductId:    orderInfo.ProductId,
			ProductName:  productName,
			OrderAmount:  agentOrder.OrderAmount,
			RebateAmount: orderInfo.RebateAmount,
			CreateTime:   orderInfo.CreateTime.Format("2006-01-02 15:04:05"),
		})
	}

	return resultList, total, nil
}

// getInviteList 获取邀请列表
func (l *GetSubordinateContributionDetailLogic) getInviteList(ctx context.Context, subordinateId string, page, pageSize int64) ([]types.InviteItem, int64, error) {
	// 查询总数
	builder := l.svcCtx.AgentRelationModel.SelectBuilder().
		Where("parent_id = ? AND relation_type = ? AND del_state = ?", subordinateId, 1, globalkey.DelStateNo)
	total, err := l.svcCtx.AgentRelationModel.FindCount(ctx, builder, "id")
	if err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (page - 1) * pageSize
	builder = builder.OrderBy("create_time DESC").
		Limit(uint64(pageSize)).Offset(uint64(offset))
	relations, err := l.svcCtx.AgentRelationModel.FindAll(ctx, builder, "")
	if err != nil {
		return nil, 0, err
	}

	// 组装邀请列表
	var inviteList []types.InviteItem
	for _, relation := range relations {
		// 查询被邀请的代理信息
		invitedAgent, err := l.svcCtx.AgentModel.FindOne(ctx, relation.ChildId)
		if err != nil {
			continue
		}

		// 获取等级名称
		levelName := ""
		switch invitedAgent.Level {
		case 1:
			levelName = "普通"
		case 2:
			levelName = "黄金"
		case 3:
			levelName = "钻石"
		}

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

		inviteList = append(inviteList, types.InviteItem{
			AgentId:    invitedAgent.Id,
			Level:      invitedAgent.Level,
			LevelName:  levelName,
			Mobile:     mobile,
			CreateTime: relation.CreateTime.Format("2006-01-02 15:04:05"),
		})
	}

	return inviteList, total, nil
}
