package agent

import (
	"context"
	"fmt"
	"time"

	"jnc-server/common/ctxdata"
	"jnc-server/common/xerr"

	"github.com/pkg/errors"

	"jnc-server/app/main/api/internal/svc"
	"jnc-server/app/main/api/internal/types"
	"jnc-server/app/main/model"

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

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

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

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

	// 查询代理信息
	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)
	}

	// 查询钱包信息
	wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agent.Id)
	if err != nil && !errors.Is(err, model.ErrNotFound) {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询钱包信息失败, %v", err)
	}
	if wallet == nil {
		// 如果没有钱包，创建一个空的
		wallet = &model.AgentWallet{
			Balance:       0,
			TotalEarnings: 0,
		}
	}

	// 获取今日统计数据（使用佣金表）
	today := time.Now().Format("2006-01-02")
	todayStart, _ := time.Parse("2006-01-02", today)
	todayEnd := todayStart.Add(24 * time.Hour)

	// 今日订单数和佣金
	todayOrders, todayEarnings, err := l.getCommissionStats(l.ctx, agent.Id, todayStart, todayEnd)
	if err != nil {
		logx.Errorf("获取今日佣金统计失败: %v", err)
		todayOrders = 0
		todayEarnings = 0
	}

	// 本月订单数和佣金
	monthStart := time.Now().AddDate(0, 0, -time.Now().Day()+1) // 本月1号
	monthStart = time.Date(monthStart.Year(), monthStart.Month(), monthStart.Day(), 0, 0, 0, 0, monthStart.Location())
	_, monthEarnings, err := l.getCommissionStats(l.ctx, agent.Id, monthStart, time.Now())
	if err != nil {
		logx.Errorf("获取本月佣金统计失败: %v", err)
		monthEarnings = 0
	}

	// 总订单数和佣金
	totalOrders, totalEarnings, err := l.getCommissionStats(l.ctx, agent.Id, time.Time{}, time.Now())
	if err != nil {
		logx.Errorf("获取总佣金统计失败: %v", err)
		totalOrders = 0
		totalEarnings = 0
	}

	// 构建推广链接
	domain := l.svcCtx.Config.Promotion.OfficialDomain
	promotionLink := fmt.Sprintf("%s/pages/query/index?agentCode=%d", domain, agent.AgentCode)

	// 获取佣金率（从配置中读取，默认为20%）
	commissionRate := l.getCommissionRate()

	return &types.AgentDashboardResp{
		Statistics: types.DashboardStatistics{
			TodayOrders:    todayOrders,
			TodayEarnings:  fmt.Sprintf("%.2f", todayEarnings),
			MonthEarnings:  fmt.Sprintf("%.2f", monthEarnings),
			TotalOrders:    totalOrders,
			TotalEarnings:  fmt.Sprintf("%.2f", totalEarnings),
			CommissionRate: commissionRate,
			CurrentBalance: fmt.Sprintf("%.2f", wallet.Balance),
			FrozenBalance:  fmt.Sprintf("%.2f", wallet.FrozenAmount),
		},
		PromotionLink: promotionLink,
		Product: types.DashboardProduct{
			Name:        "个人大数据",
			Price:       "29.90",
			Description: "全面个人数据风险报告",
		},
	}, nil
}

// getCommissionStats 获取指定时间段的佣金统计
func (l *GetAgentDashboardLogic) getCommissionStats(ctx context.Context, agentId string, startTime, endTime time.Time) (int64, float64, error) {
	builder := l.svcCtx.AgentCommissionModel.SelectBuilder()

	// 添加代理ID条件
	builder = builder.Where("agent_id = ?", agentId)

	// 添加时间范围条件
	if !startTime.IsZero() {
		builder = builder.Where("create_time >= ?", startTime)
	}
	if !endTime.IsZero() {
		builder = builder.Where("create_time < ?", endTime)
	}

	// 只统计已发放的佣金
	builder = builder.Where("status = ?", 1)

	// 获取数量
	count, err := l.svcCtx.AgentCommissionModel.FindCount(ctx, builder, "id")
	if err != nil {
		return 0, 0, err
	}

	// 获取总额
	sum, err := l.svcCtx.AgentCommissionModel.FindSum(ctx, builder, "amount")
	if err != nil {
		return count, 0, err
	}

	return count, sum, nil
}

// getCommissionRate 获取佣金率
func (l *GetAgentDashboardLogic) getCommissionRate() string {
	// TODO: 从配置或数据库中读取佣金率
	// 目前返回固定值20%
	return "20%"
}
