package card_redeem_account

import (
	"context"
	"fmt"
	v1 "kami/api/card_info_walmart/v1"
	"kami/internal/consts"
	"kami/internal/dao"
	"kami/internal/model"
	"kami/internal/model/entity"
	"kami/utility/config"

	"github.com/duke-git/lancet/v2/slice"
	"github.com/gogf/gf/v2/database/gdb"
)

func (a *sCardRedeemAccount) GroupStats(ctx context.Context, input *model.RedeemAccountGroupStatsInput, tx gdb.TX) (total int, output []*model.RedeemAccountGroupStatsOutput, err error) {
	sqlQuery := `
		SELECT
			DATE(card_redeem_order_info.created_at) AS order_date,
			card_redeem_account_group.id AS group_id,
			card_redeem_account_group.name AS group_name,
			card_redeem_account_group.created_user_id AS group_created_user_id,
			COUNT(card_redeem_order_info.order_no) AS count,
			SUM(card_redeem_order_info.actual_amount) AS sum,
			sys_user.username
		FROM
			card_redeem_order_info
			LEFT JOIN card_redeem_account_info ON card_redeem_account_info.id = card_redeem_order_info.account_id
			LEFT JOIN card_redeem_account_group ON card_redeem_account_info.group_id = card_redeem_account_group.id
			LEFT JOIN sys_user ON sys_user.id=card_redeem_account_group.created_user_id
		WHERE
			(card_redeem_order_info.order_status = 1 OR card_redeem_order_info.order_status = 8)
	`

	if input.Date != nil {
		sqlQuery += fmt.Sprintf(" AND DATE(card_redeem_order_info.created_at) = '%s'", input.Date.Layout("2006-01-02"))
	}

	if input.Category != "" {
		sqlQuery += fmt.Sprintf(" AND card_redeem_account_info.category = '%s'", input.Category)
	}

	if input.CreatedUserId != "" {
		sqlQuery += fmt.Sprintf(" AND card_redeem_account_info.create_user_id = '%s'", input.CreatedUserId)
	}

	if input.Username != "" {
		sqlQuery += fmt.Sprintf(" AND sys_user.username LIKE '%%%s%%'", input.Username)
	}

	if input.Name != "" {
		sqlQuery += fmt.Sprintf(" AND card_redeem_account_group.name LIKE '%%%s%%'", input.Name)
	}

	sqlQuery += `
		GROUP BY
			order_date,
			group_id
	`
	// 分页
	var sqlQueryPage string
	if input.Current != 0 && input.PageSize != 0 {
		offset := (input.Current - 1) * input.PageSize
		limit := input.PageSize
		sqlQueryPage = sqlQuery + fmt.Sprintf(" LIMIT %d, %d", offset, limit)
	} else {
		sqlQueryPage = sqlQuery
	}
	m := dao.V1CardRedeemAccountGroup.Ctx(ctx).Unscoped().DB(config.GetDatabaseV1())
	if tx != nil {
		m = m.TX(tx)
	}

	var data []*v1.V1CardRedeemAccountGroupStatsEntity
	// 查询总数
	err = m.Raw(sqlQuery).Scan(&data)
	if err != nil {
		return
	}
	total = len(data)
	err = m.Raw(sqlQueryPage).Scan(&data)
	if err != nil {
		return
	}

	// 获取所有分组 id
	groupIds := slice.Unique(slice.Filter(slice.Map(data, func(index int, item *v1.V1CardRedeemAccountGroupStatsEntity) int {
		return item.GroupId
	}),
		func(index int, item int) bool {
			return item != 0
		},
	))

	var accountInfos []*entity.V1CardRedeemAccountInfo
	// 获取所有账户
	m = dao.V1CardRedeemAccountInfo.Ctx(ctx).Unscoped().DB(config.GetDatabaseV1())
	if tx != nil {
		m = m.TX(tx)
	}
	err = m.WhereIn(dao.V1CardRedeemAccountInfo.Columns().Id, groupIds).Scan(&accountInfos)
	if err != nil {
		return
	}

	output = make([]*model.RedeemAccountGroupStatsOutput, 0)
	for _, group := range data {
		targetAccountInfos := slice.Filter(accountInfos, func(index int, item *entity.V1CardRedeemAccountInfo) bool {
			return item.GroupId == group.GroupId
		})
		output = append(output, &model.RedeemAccountGroupStatsOutput{
			V1CardRedeemAccountGroupEntity: &v1.V1CardRedeemAccountGroupEntity{
				V1CardRedeemAccountGroupStatsEntity: group,
				Account: &v1.V1CardRedeemAccountGroupEntityAccount{
					Total: len(targetAccountInfos),
					Normal: len(slice.Filter(targetAccountInfos, func(index int, item *entity.V1CardRedeemAccountInfo) bool {
						return consts.RedeemAccountStatus(item.Status) == consts.RedeemAccountNormal && item.DeletedAt == nil
					})),
					UnNormal: len(slice.Filter(targetAccountInfos, func(index int, item *entity.V1CardRedeemAccountInfo) bool {
						return consts.RedeemAccountStatus(item.Status) != consts.RedeemAccountNormal && item.DeletedAt == nil
					})),
					Deleted: len(slice.Filter(targetAccountInfos, func(index int, item *entity.V1CardRedeemAccountInfo) bool {
						return item.DeletedAt != nil
					})),
				},
			},
		})
	}
	return
}
