package admin_dashboard

import (
	"bdqr-server/app/main/api/internal/service"
	"context"
	"time"

	"bdqr-server/app/main/api/internal/svc"
	"bdqr-server/app/main/api/internal/types"
	"bdqr-server/common/globalkey"
	"bdqr-server/common/xerr"

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

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

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

func (l *AdminGetDashboardStatisticsLogic) AdminGetDashboardStatistics() (resp *types.AdminGetDashboardStatisticsResp, err error) {
	// 使用Asia/Shanghai时区
	loc, _ := time.LoadLocation("Asia/Shanghai")
	now := time.Now().In(loc)

	// 计算时间范围
	todayStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc)
	todayEnd := todayStart.AddDate(0, 0, 1)
	yesterdayStart := todayStart.AddDate(0, 0, -1)
	yesterdayEnd := todayStart
	monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, loc)
	monthEnd := monthStart.AddDate(0, 1, 0)

	// 1. 订单统计
	orderStats, err := l.calculateOrderStatistics(todayStart, todayEnd, yesterdayStart, yesterdayEnd, monthStart, monthEnd)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算订单统计失败, %v", err)
	}

	// 2. 营收统计
	revenueStats, err := l.calculateRevenueStatistics(todayStart, todayEnd, yesterdayStart, yesterdayEnd, monthStart, monthEnd)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算营收统计失败, %v", err)
	}

	// 3. 代理统计
	agentStats, err := l.calculateAgentStatistics(todayStart, monthStart)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算代理统计失败, %v", err)
	}

	// 4. 利润统计
	profitStats, err := l.calculateProfitStatistics(todayStart, todayEnd, monthStart, monthEnd, revenueStats)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算利润统计失败, %v", err)
	}

	// 5. 订单趋势（最近7天）
	orderTrend, err := l.calculateOrderTrend(now, loc)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算订单趋势失败, %v", err)
	}

	// 6. 营收趋势（最近7天）
	revenueTrend, err := l.calculateRevenueTrend(now, loc)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算营收趋势失败, %v", err)
	}

	return &types.AdminGetDashboardStatisticsResp{
		OrderStats:   orderStats,
		RevenueStats: revenueStats,
		AgentStats:   agentStats,
		ProfitStats:  profitStats,
		OrderTrend:   orderTrend,
		RevenueTrend: revenueTrend,
	}, nil
}

// calculateOrderStatistics 计算订单统计
func (l *AdminGetDashboardStatisticsLogic) calculateOrderStatistics(todayStart, todayEnd, yesterdayStart, yesterdayEnd, monthStart, monthEnd time.Time) (types.AdminOrderStatistics, error) {
	var stats types.AdminOrderStatistics

	// 今日订单数
	todayBuilder := l.svcCtx.OrderModel.SelectBuilder().
		Where("status = ? AND create_time >= ? AND create_time < ?", "paid", todayStart, todayEnd)
	todayCount, err := l.svcCtx.OrderModel.FindCount(l.ctx, todayBuilder, "id")
	if err != nil {
		return stats, err
	}
	stats.TodayCount = todayCount

	// 昨日订单数
	yesterdayBuilder := l.svcCtx.OrderModel.SelectBuilder().
		Where("status = ? AND create_time >= ? AND create_time < ?", "paid", yesterdayStart, yesterdayEnd)
	yesterdayCount, err := l.svcCtx.OrderModel.FindCount(l.ctx, yesterdayBuilder, "id")
	if err != nil {
		return stats, err
	}
	stats.YesterdayCount = yesterdayCount

	// 当月订单数
	monthBuilder := l.svcCtx.OrderModel.SelectBuilder().
		Where("status = ? AND create_time >= ? AND create_time < ?", "paid", monthStart, monthEnd)
	monthCount, err := l.svcCtx.OrderModel.FindCount(l.ctx, monthBuilder, "id")
	if err != nil {
		return stats, err
	}
	stats.MonthCount = monthCount

	// 总订单数
	totalBuilder := l.svcCtx.OrderModel.SelectBuilder().
		Where("status = ?", "paid")
	totalCount, err := l.svcCtx.OrderModel.FindCount(l.ctx, totalBuilder, "id")
	if err != nil {
		return stats, err
	}
	stats.TotalCount = totalCount

	// 计算变化率
	if stats.YesterdayCount > 0 {
		stats.ChangeRate = float64(stats.TodayCount-stats.YesterdayCount) / float64(stats.YesterdayCount) * 100
	} else if stats.TodayCount > 0 {
		stats.ChangeRate = 100 // 从0增长到有值，算100%增长
	}

	return stats, nil
}

// calculateRevenueStatistics 计算营收统计
func (l *AdminGetDashboardStatisticsLogic) calculateRevenueStatistics(todayStart, todayEnd, yesterdayStart, yesterdayEnd, monthStart, monthEnd time.Time) (types.AdminRevenueStatistics, error) {
	var stats types.AdminRevenueStatistics

	// 今日营收
	todayBuilder := l.svcCtx.OrderModel.SelectBuilder().
		Where("status = ? AND create_time >= ? AND create_time < ?", "paid", todayStart, todayEnd)
	todayAmount, err := l.svcCtx.OrderModel.FindSum(l.ctx, todayBuilder, "amount")
	if err != nil {
		return stats, err
	}
	stats.TodayAmount = todayAmount

	// 昨日营收
	yesterdayBuilder := l.svcCtx.OrderModel.SelectBuilder().
		Where("status = ? AND create_time >= ? AND create_time < ?", "paid", yesterdayStart, yesterdayEnd)
	yesterdayAmount, err := l.svcCtx.OrderModel.FindSum(l.ctx, yesterdayBuilder, "amount")
	if err != nil {
		return stats, err
	}
	stats.YesterdayAmount = yesterdayAmount

	// 当月营收
	monthBuilder := l.svcCtx.OrderModel.SelectBuilder().
		Where("status = ? AND create_time >= ? AND create_time < ?", "paid", monthStart, monthEnd)
	monthAmount, err := l.svcCtx.OrderModel.FindSum(l.ctx, monthBuilder, "amount")
	if err != nil {
		return stats, err
	}
	stats.MonthAmount = monthAmount

	// 总营收
	totalBuilder := l.svcCtx.OrderModel.SelectBuilder().
		Where("status = ?", "paid")
	totalAmount, err := l.svcCtx.OrderModel.FindSum(l.ctx, totalBuilder, "amount")
	if err != nil {
		return stats, err
	}
	stats.TotalAmount = totalAmount

	// 计算变化率
	if stats.YesterdayAmount > 0 {
		stats.ChangeRate = (stats.TodayAmount - stats.YesterdayAmount) / stats.YesterdayAmount * 100
	} else if stats.TodayAmount > 0 {
		stats.ChangeRate = 100 // 从0增长到有值，算100%增长
	}

	return stats, nil
}

// calculateAgentStatistics 计算代理统计
func (l *AdminGetDashboardStatisticsLogic) calculateAgentStatistics(todayStart, monthStart time.Time) (types.AdminAgentStatistics, error) {
	var stats types.AdminAgentStatistics

	// 代理总数
	totalBuilder := l.svcCtx.AgentModel.SelectBuilder()
	totalCount, err := l.svcCtx.AgentModel.FindCount(l.ctx, totalBuilder, "id")
	if err != nil {
		return stats, err
	}
	stats.TotalCount = totalCount

	// 今日新增
	todayBuilder := l.svcCtx.AgentModel.SelectBuilder().
		Where("create_time >= ?", todayStart)
	todayNew, err := l.svcCtx.AgentModel.FindCount(l.ctx, todayBuilder, "id")
	if err != nil {
		return stats, err
	}
	stats.TodayNew = todayNew

	// 当月新增
	monthBuilder := l.svcCtx.AgentModel.SelectBuilder().
		Where("create_time >= ?", monthStart)
	monthNew, err := l.svcCtx.AgentModel.FindCount(l.ctx, monthBuilder, "id")
	if err != nil {
		return stats, err
	}
	stats.MonthNew = monthNew

	return stats, nil
}

// calculateProfitStatistics 计算利润统计
func (l *AdminGetDashboardStatisticsLogic) calculateProfitStatistics(todayStart, todayEnd, monthStart, monthEnd time.Time, revenueStats types.AdminRevenueStatistics) (types.AdminProfitStatistics, error) {
	var stats types.AdminProfitStatistics

	// 税务成本比例（6%）
	const companyTaxRate = 0.06

	// 今日利润计算
	// 今日营收
	todayRevenue := revenueStats.TodayAmount
	// 今日佣金
	todayCommissionBuilder := l.svcCtx.AgentCommissionModel.SelectBuilder().
		Where("del_state = ? AND status != ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 3, todayStart, todayEnd)
	todayCommission, err := l.svcCtx.AgentCommissionModel.FindSum(l.ctx, todayCommissionBuilder, "amount")
	if err != nil {
		return stats, err
	}
	// 今日返利
	todayRebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
		Where("del_state = ? AND status != ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 3, todayStart, todayEnd)
	todayRebate, err := l.svcCtx.AgentRebateModel.FindSum(l.ctx, todayRebateBuilder, "rebate_amount")
	if err != nil {
		return stats, err
	}
	// 今日税务成本（订单金额的6%）
	todayCompanyTax := todayRevenue * companyTaxRate
	// 今日提现收税（agent_withdrawal_tax表中tax_status=2的tax_amount总和）
	todayTaxIncomeBuilder := l.svcCtx.AgentWithdrawalTaxModel.SelectBuilder().
		Where("del_state = ? AND tax_status = ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 2, todayStart, todayEnd)
	todayTaxIncome, err := l.svcCtx.AgentWithdrawalTaxModel.FindSum(l.ctx, todayTaxIncomeBuilder, "tax_amount")
	if err != nil {
		return stats, err
	}
	// 今日API调用成本
	todayApiCost := 0.0
	if l.svcCtx.TianyuanapiCallLogService != nil {
		logx.Infof("开始获取今日API调用成本，时间范围: %v 到 %v", todayStart, todayEnd)
		todayApiStats, err := l.svcCtx.TianyuanapiCallLogService.GetStatistics(l.ctx, service.StatisticsFilter{
			StartDate: todayStart,
			EndDate:   todayEnd,
		})
		if err != nil {
			logx.Errorf("获取今日API调用成本失败: %v", err)
		} else {
			todayApiCost = todayApiStats.TotalCost
			logx.Infof("今日API调用成本统计完成，总成本: %f", todayApiCost)
		}
	} else {
		logx.Errorf("TianyuanapiCallLogService 未初始化，无法获取API调用成本")
	}
	// 今日利润 = 营收 - 佣金 - 返利 - 税务成本 - API调用成本 + 提现收税
	stats.TodayProfit = todayRevenue - todayCommission - todayRebate - todayCompanyTax - todayApiCost + todayTaxIncome
	if todayRevenue > 0 {
		stats.TodayProfitRate = stats.TodayProfit / todayRevenue * 100
	}
	// 今日明细
	stats.TodayDetail = types.AdminProfitDetail{
		Revenue:    todayRevenue,
		Commission: todayCommission,
		Rebate:     todayRebate,
		CompanyTax: todayCompanyTax,
		ApiCost:    todayApiCost,
		TaxIncome:  todayTaxIncome,
		Profit:     stats.TodayProfit,
		ProfitRate: stats.TodayProfitRate,
	}

	// 当月利润计算
	// 当月营收
	monthRevenue := revenueStats.MonthAmount
	// 当月佣金
	monthCommissionBuilder := l.svcCtx.AgentCommissionModel.SelectBuilder().
		Where("del_state = ? AND status != ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 3, monthStart, monthEnd)
	monthCommission, err := l.svcCtx.AgentCommissionModel.FindSum(l.ctx, monthCommissionBuilder, "amount")
	if err != nil {
		return stats, err
	}
	// 当月返利
	monthRebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
		Where("del_state = ? AND status != ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 3, monthStart, monthEnd)
	monthRebate, err := l.svcCtx.AgentRebateModel.FindSum(l.ctx, monthRebateBuilder, "rebate_amount")
	if err != nil {
		return stats, err
	}
	// 当月税务成本
	monthCompanyTax := monthRevenue * companyTaxRate
	// 当月提现收税
	monthTaxIncomeBuilder := l.svcCtx.AgentWithdrawalTaxModel.SelectBuilder().
		Where("del_state = ? AND tax_status = ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 2, monthStart, monthEnd)
	monthTaxIncome, err := l.svcCtx.AgentWithdrawalTaxModel.FindSum(l.ctx, monthTaxIncomeBuilder, "tax_amount")
	if err != nil {
		return stats, err
	}
	// 当月API调用成本
	monthApiCost := 0.0
	if l.svcCtx.TianyuanapiCallLogService != nil {
		logx.Infof("开始获取当月API调用成本，时间范围: %v 到 %v", monthStart, monthEnd)
		monthApiStats, err := l.svcCtx.TianyuanapiCallLogService.GetStatistics(l.ctx, service.StatisticsFilter{
			StartDate: monthStart,
			EndDate:   monthEnd,
		})
		if err != nil {
			logx.Errorf("获取当月API调用成本失败: %v", err)
		} else {
			monthApiCost = monthApiStats.TotalCost
			logx.Infof("当月API调用成本统计完成，总成本: %f", monthApiCost)
		}
	} else {
		logx.Errorf("TianyuanapiCallLogService 未初始化，无法获取API调用成本")
	}
	// 当月利润
	stats.MonthProfit = monthRevenue - monthCommission - monthRebate - monthCompanyTax - monthApiCost + monthTaxIncome
	if monthRevenue > 0 {
		stats.MonthProfitRate = stats.MonthProfit / monthRevenue * 100
	}
	// 当月明细
	stats.MonthDetail = types.AdminProfitDetail{
		Revenue:    monthRevenue,
		Commission: monthCommission,
		Rebate:     monthRebate,
		CompanyTax: monthCompanyTax,
		ApiCost:    monthApiCost,
		TaxIncome:  monthTaxIncome,
		Profit:     stats.MonthProfit,
		ProfitRate: stats.MonthProfitRate,
	}

	// 总利润计算
	// 总营收
	totalRevenue := revenueStats.TotalAmount
	// 总佣金
	totalCommissionBuilder := l.svcCtx.AgentCommissionModel.SelectBuilder().
		Where("del_state = ? AND status != ?", globalkey.DelStateNo, 3)
	totalCommission, err := l.svcCtx.AgentCommissionModel.FindSum(l.ctx, totalCommissionBuilder, "amount")
	if err != nil {
		return stats, err
	}
	// 总返利
	totalRebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder().
		Where("status != ?", 3)
	totalRebate, err := l.svcCtx.AgentRebateModel.FindSum(l.ctx, totalRebateBuilder, "rebate_amount")
	if err != nil {
		return stats, err
	}
	// 总税务成本
	totalCompanyTax := totalRevenue * companyTaxRate
	// 总提现收税
	totalTaxIncomeBuilder := l.svcCtx.AgentWithdrawalTaxModel.SelectBuilder().
		Where("tax_status = ?", 2)
	totalTaxIncome, err := l.svcCtx.AgentWithdrawalTaxModel.FindSum(l.ctx, totalTaxIncomeBuilder, "tax_amount")
	if err != nil {
		return stats, err
	}
	// 总API调用成本
	totalApiCost := 0.0
	if l.svcCtx.TianyuanapiCallLogService != nil {
		logx.Infof("开始获取总API调用成本（无时间限制）")
		totalApiStats, err := l.svcCtx.TianyuanapiCallLogService.GetStatistics(l.ctx, service.StatisticsFilter{})
		if err != nil {
			logx.Errorf("获取总API调用成本失败: %v", err)
		} else {
			totalApiCost = totalApiStats.TotalCost
			logx.Infof("总API调用成本统计完成，总成本: %f", totalApiCost)
		}
	} else {
		logx.Errorf("TianyuanapiCallLogService 未初始化，无法获取API调用成本")
	}
	// 总利润
	stats.TotalProfit = totalRevenue - totalCommission - totalRebate - totalCompanyTax - totalApiCost + totalTaxIncome
	if totalRevenue > 0 {
		stats.TotalProfitRate = stats.TotalProfit / totalRevenue * 100
	}
	// 总计明细
	stats.TotalDetail = types.AdminProfitDetail{
		Revenue:    totalRevenue,
		Commission: totalCommission,
		Rebate:     totalRebate,
		CompanyTax: totalCompanyTax,
		ApiCost:    totalApiCost,
		TaxIncome:  totalTaxIncome,
		Profit:     stats.TotalProfit,
		ProfitRate: stats.TotalProfitRate,
	}

	return stats, nil
}

// calculateOrderTrend 计算订单趋势（最近7天）
func (l *AdminGetDashboardStatisticsLogic) calculateOrderTrend(now time.Time, loc *time.Location) ([]types.AdminTrendData, error) {
	var trend []types.AdminTrendData

	// 计算最近7天的日期
	for i := 6; i >= 0; i-- {
		date := now.AddDate(0, 0, -i)
		dateStart := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, loc)
		dateEnd := dateStart.AddDate(0, 0, 1)

		// 查询当天的订单数
		builder := l.svcCtx.OrderModel.SelectBuilder().
			Where("status = ? AND create_time >= ? AND create_time < ?", "paid", dateStart, dateEnd)
		count, err := l.svcCtx.OrderModel.FindCount(l.ctx, builder, "id")
		if err != nil {
			return nil, err
		}

		trend = append(trend, types.AdminTrendData{
			Date:  date.Format("01-02"),
			Value: float64(count),
		})
	}

	return trend, nil
}

// calculateRevenueTrend 计算营收趋势（最近7天）
func (l *AdminGetDashboardStatisticsLogic) calculateRevenueTrend(now time.Time, loc *time.Location) ([]types.AdminTrendData, error) {
	var trend []types.AdminTrendData

	// 计算最近7天的日期
	for i := 6; i >= 0; i-- {
		date := now.AddDate(0, 0, -i)
		dateStart := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, loc)
		dateEnd := dateStart.AddDate(0, 0, 1)

		// 查询当天的营收
		builder := l.svcCtx.OrderModel.SelectBuilder().
			Where("status = ? AND create_time >= ? AND create_time < ?", "paid", dateStart, dateEnd)
		amount, err := l.svcCtx.OrderModel.FindSum(l.ctx, builder, "amount")
		if err != nil {
			return nil, err
		}

		trend = append(trend, types.AdminTrendData{
			Date:  date.Format("01-02"),
			Value: amount,
		})
	}

	return trend, nil
}
