package order

import (
	"context"
	"slices"
	"time"

	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
	"github.com/duke-git/lancet/v2/mathutil"
	"github.com/duke-git/lancet/v2/slice"
)

// Summary 订单总结
type Summary struct {
	TotalNum      int       `json:"totalNum" orm:"total_num"`           // 提交订单数
	TotalAmount   float64   `json:"totalAmount" orm:"total_amount"`     // 订单总金额
	Rate          float64   `json:"rate" orm:"rate"`                    // 成功率
	SuccessNum    int       `json:"successNum" orm:"success_num"`       // 成功订单数
	SuccessAmount float64   `json:"successAmount" orm:"success_amount"` // 成功订单总金额
	Date          time.Time `json:"date" orm:"date"`                    // 日期
}

func GetSummaryByRoadAndMerchant(ctx context.Context, roadUid, merchantUid string) (summariesList []Summary) {
	o := orm.NewOrm()
	summariesList = make([]Summary, 0)
	sql := `
	SELECT
		COUNT(id) AS total_num,
		SUM(order_info.order_amount) AS total_amount,
		COUNT(CASE WHEN order_info.status = 'success' THEN 1 END) AS success_num,
		SUM(CASE WHEN order_info.status = 'success' THEN order_info.order_amount ELSE 0 END) AS success_amount,
		DATE(create_time) AS date
	FROM
		order_info
	WHERE
		(1=1)
		AND order_info.road_uid = ?
		AND order_info.merchant_uid = ?
	GROUP BY
		DATE(create_time)
	ORDER BY DATE(create_time) DESC
	`

	o.RawWithCtx(ctx, sql, roadUid, merchantUid).QueryRows(&summariesList)

	if len(summariesList) == 0 {
		return
	}

	// 补齐从今天到第一天中空缺天的数据
	for date := time.Now(); date.After(summariesList[0].Date); date = date.AddDate(0, 0, -1) {
		if slice.ContainBy(summariesList, func(item Summary) bool {
			return item.Date.Format("2006-01-02") == date.Format("2006-01-02")
		}) {
			continue
		}
		summariesList = append(summariesList, Summary{Date: date})
	}

	// 计算成功率
	for _, summary := range summariesList {
		if summary.TotalNum == 0 {
			summary.Rate = 0
			continue
		}
		summary.Rate = mathutil.RoundToFloat(float64(summary.SuccessNum)/float64(summary.TotalNum)*100, 2)
	}

	//按照时间排序
	slices.SortStableFunc(summariesList, func(a, b Summary) int {
		return int(b.Date.Unix() - a.Date.Unix())
	})
	return
}

func GetSummaryByMerchant(ctx context.Context, merchantUid string) (summariesList []Summary) {
	o := orm.NewOrm()
	summariesList = make([]Summary, 0)
	sql := `
	SELECT
		COUNT(id) AS total_num,
		SUM(order_info.order_amount) AS total_amount,
		COUNT(CASE WHEN order_info.status = 'success' THEN 1 END) AS success_num,
		SUM(CASE WHEN order_info.status = 'success' THEN order_info.order_amount ELSE 0 END) AS success_amount,
		DATE(create_time) AS date
	FROM
		order_info
	WHERE
		(1=1)
		AND order_info.merchant_uid = ?
	GROUP BY
		DATE(create_time)
	`
	if _, err := o.RawWithCtx(ctx, sql, merchantUid).QueryRows(&summariesList); err != nil {
		logs.Error("GetSummaryByMerchant error: %v", err)
		return
	}

	if len(summariesList) == 0 {
		return
	}

	// 补齐从今天到第一天中空缺天的数据
	firstDate := summariesList[0].Date
	for date := time.Now(); date.After(firstDate); date = date.AddDate(0, 0, -1) {
		if slice.ContainBy(summariesList, func(item Summary) bool {
			return item.Date.Format("2006-01-02") == date.Format("2006-01-02")
		}) {
			continue
		}
		summariesList = append(summariesList, Summary{Date: date})
	}

	// 计算成功率
	for _, summary := range summariesList {
		if summary.TotalNum == 0 {
			summary.Rate = 0
			continue
		}
		summary.Rate = mathutil.RoundToFloat(float64(summary.SuccessNum)/float64(summary.TotalNum)*100, 2)
	}
	slices.SortStableFunc(summariesList, func(a, b Summary) int {
		return int(b.Date.Unix() - a.Date.Unix())
	})
	return
}
