package merchant_order

import (
	"context"
	"fmt"

	"kami/internal/dao"
	"kami/internal/model"
	"kami/internal/service"
	"kami/utility/config"

	"github.com/gogf/gf/v2/os/gtime"
)

func init() {
	service.RegisterOrderSummary(New())
}

func New() *sOrderSummary {
	return &sOrderSummary{}
}

type sOrderSummary struct{}

func (s *sOrderSummary) GetList(ctx context.Context, input model.OrderSummaryListInput) (total int, list []*model.OrderSummaryListOutput, err error) {
	var (
		column = dao.V1OrderInfo.Columns()
	)
	list = make([]*model.OrderSummaryListOutput, 0)
	total = 0
	m := dao.V1OrderInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if input.RoadUid != "" {
		m = m.Where(column.RoadUid, input.RoadUid)
	}
	switch input.LoginType {
	case model.LoginTypeMerchant:
		m = m.Where(column.MerchantUid, input.UserId)
	case model.LoginTypeAuth:
		m = m.Where(false)
	}
	if input.Date != "" {
		inputDate := gtime.NewFromStrFormat(input.Date, "Y-m-d")
		m = m.WhereBetween(column.CreateTime, inputDate.StartOfDay(), inputDate.EndOfDay())
	}
	_ = m.Fields(column.MerchantName, column.MerchantUid).
		FieldSum(fmt.Sprintf("CASE WHEN %s = 'success' THEN %s ELSE 0 END", column.Status, column.ShowAmount), "succeed_show_amount").
		FieldSum(fmt.Sprintf("CASE WHEN %s = 'success' THEN %s ELSE 0 END", column.Status, column.FactAmount), "succeed_fact_amount").
		FieldSum(fmt.Sprintf("CASE WHEN %s = 'success' THEN 1 ELSE 0 END", column.Status), "succeed_count").
		FieldSum(fmt.Sprintf("CASE WHEN %s = 'wait' THEN 1 ELSE 0 END", column.Status), "waited_count").
		FieldSum(fmt.Sprintf("CASE WHEN %s = 'fail' THEN 1 ELSE 0 END", column.Status), "failed_count").
		Fields(fmt.Sprintf("SUM(CASE WHEN %s = 'success' THEN 1 ELSE 0 END) / COUNT(*) AS rate", column.Status)).
		FieldSum(column.ShowAmount, "total_show_amount").
		FieldSum(column.FactAmount, "total_fact_amount").
		FieldCount(column.Id, "total_count").
		Fields(fmt.Sprintf("DATE(%s) AS date", column.CreateTime)).
		Group(
			fmt.Sprintf("DATE(%s)", column.CreateTime),
			column.MerchantName,
			column.MerchantUid,
		).
		OrderDesc(fmt.Sprintf("DATE(%s)", column.CreateTime)).
		Page(input.Current, input.PageSize).
		ScanAndCount(&list, &total, false)
	return
}

func (s *sOrderSummary) GetDailyStats(ctx context.Context, input *model.OrderSummaryDailyListInput) (total int, list []*model.OrderSummaryDailyListOutput, err error) {
	var (
		column = dao.V1OrderInfo.Columns()
	)
	list = make([]*model.OrderSummaryDailyListOutput, 0)
	total = 0
	m := dao.V1OrderInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if len(input.RoadUid) > 0 {
		m = m.WhereIn(column.RoadUid, input.RoadUid)
	}
	if len(input.MerchantUid) > 0 {
		m = m.WhereIn(column.MerchantUid, input.MerchantUid)
	}
	if len(input.DateRange) > 0 {
		m = m.WhereBetween(column.CreateTime, input.DateRange[0].EndOfDay(), input.DateRange[1].EndOfDay())
	} else {
		m = m.WhereBetween(column.CreateTime, gtime.Now().AddDate(0, 0, -15).StartOfDay(), gtime.Now().EndOfDay())
	}
	_ = m.Fields(column.MerchantName, column.MerchantUid, column.RoadUid, column.RoadName).
		FieldSum(fmt.Sprintf("CASE WHEN %s = 'success' THEN %s ELSE 0 END", column.Status, column.ShowAmount), "succeed_show_amount").
		FieldSum(fmt.Sprintf("CASE WHEN %s = 'success' THEN %s ELSE 0 END", column.Status, column.FactAmount), "succeed_fact_amount").
		FieldSum(fmt.Sprintf("CASE WHEN %s = 'success' THEN 1 ELSE 0 END", column.Status), "succeed_count").
		FieldSum(fmt.Sprintf("CASE WHEN %s = 'wait' THEN 1 ELSE 0 END", column.Status), "waited_count").
		FieldSum(fmt.Sprintf("CASE WHEN %s = 'fail' THEN 1 ELSE 0 END", column.Status), "failed_count").
		Fields(fmt.Sprintf("SUM(CASE WHEN %s = 'success' THEN 1 ELSE 0 END) / COUNT(*) AS rate", column.Status)).
		FieldSum(column.ShowAmount, "total_show_amount").
		FieldSum(column.FactAmount, "total_fact_amount").
		FieldCount(column.Id, "total_count").
		Fields(fmt.Sprintf("DATE(%s) AS date", column.CreateTime)).
		Group(
			fmt.Sprintf("DATE(%s)", column.CreateTime),
			column.MerchantUid,
			column.MerchantName,
			column.RoadUid,
			column.RoadName,
		).
		OrderDesc(fmt.Sprintf("DATE(%s)", column.CreateTime)).
		ScanAndCount(&list, &total, false)
	return
}
