package repoimpl

import (
	"context"
	"gorm.io/gorm"
	"time"
	"voucher/internal/biz/bo"
	"voucher/internal/biz/repo"
	"voucher/internal/data"
	"voucher/internal/data/model"
)

// MultiNotifyDataRepoImpl .
type MultiNotifyDataRepoImpl struct {
	Base[model.MultiNotifyDatum, bo.MultiNotifyDataBo]
	db *data.Db
}

// NewMultiNotifyDataRepoImpl .
func NewMultiNotifyDataRepoImpl(db *data.Db) repo.MultiNotifyDataRepo {
	return &MultiNotifyDataRepoImpl{db: db}
}

func (p *MultiNotifyDataRepoImpl) DB(ctx context.Context) *gorm.DB {
	return p.db.DB(ctx).WithContext(ctx).Model(model.MultiNotifyDatum{})
}

func (p *MultiNotifyDataRepoImpl) FindNoticeNumZero(ctx context.Context, fun func(ctx context.Context, rows []*bo.MultiNotifyDataBo) error) error {

	tx := p.DB(ctx).Where("notice_num = 0")
	tx.Order("id asc") // 显式清除排序，移除默认的 ORDER BY
	tx.Limit(200)

	var results = make([]*model.MultiNotifyDatum, 0)

	result := tx.FindInBatches(&results, 50, func(tx *gorm.DB, batch int) error {
		return fun(ctx, p.ToBos(results))
	})

	if result.Error != nil {
		return result.Error
	}

	return nil
}

func (p *MultiNotifyDataRepoImpl) Create(ctx context.Context, req *bo.MultiNotifyDataBo) (*bo.MultiNotifyDataBo, error) {

	now := time.Now()

	info := &model.MultiNotifyDatum{
		Source:        req.Source,
		IP:            req.IP,
		NotifyID:      req.NotifyID,
		OrderNo:       req.OrderNo,
		OutBizNo:      req.OutBizNo,
		CouponID:      req.CouponID,
		StockID:       req.StockID,
		ConsumeAmount: req.ConsumeAmount,
		ConsumeTime:   req.ConsumeTime,
		TransactionID: req.TransactionID,
		EventType:     req.EventType,
		Status:        req.Status.GetValue(),
		OriginalData:  req.OriginalData,
		NoticeNum:     0,
		CreateTime:    &now,
	}

	if err := p.DB(ctx).Create(info).Error; err != nil {
		return nil, err
	}

	return p.ToBo(info), nil
}

func (p *MultiNotifyDataRepoImpl) GetByID(ctx context.Context, id int64) (*bo.MultiNotifyDataBo, error) {

	var item model.MultiNotifyDatum

	tx := p.DB(ctx).Where(model.MultiNotifyDatum{ID: id}).First(&item)

	if tx.Error != nil {
		return nil, tx.Error
	}

	if tx.RowsAffected == 0 {
		return nil, gorm.ErrRecordNotFound
	}

	return p.ToBo(&item), nil
}

func (p *MultiNotifyDataRepoImpl) GetByNotifyID(ctx context.Context, source, notifyId string) (*bo.MultiNotifyDataBo, error) {

	var item model.MultiNotifyDatum

	tx := p.DB(ctx).Where(model.MultiNotifyDatum{Source: source, NotifyID: notifyId}).First(&item)

	if tx.Error != nil {
		return nil, tx.Error
	}

	if tx.RowsAffected == 0 {
		return nil, gorm.ErrRecordNotFound
	}

	return p.ToBo(&item), nil
}

func (p *MultiNotifyDataRepoImpl) AddNoticeNum(ctx context.Context, id int64) error {

	now := time.Now()

	u := map[string]interface{}{
		"notice_num":  gorm.Expr("notice_num + ?", 1),
		"update_time": &now,
	}

	tx := p.DB(ctx).Where("id = ?", id).Updates(u)

	if tx.Error != nil {
		return tx.Error
	}

	if tx.RowsAffected == 0 {
		return gorm.ErrRecordNotFound
	}

	return nil
}
