package repoimpl

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

// OrderNotifyRepoImpl .
type OrderNotifyRepoImpl struct {
	Base[model.OrderNotify, bo.OrderNotifyBo]
	db *data.Db
}

// NewOrderNotifyRepoImpl .
func NewOrderNotifyRepoImpl() repo.OrderNotifyRepo {
	return &OrderNotifyRepoImpl{}
}

func (p *OrderNotifyRepoImpl) DB(ctx context.Context) *gorm.DB {
	return p.db.DB(ctx).Model(model.OrderNotify{})
}

func (p *OrderNotifyRepoImpl) Create(ctx context.Context, req *bo.OrderNotifyBo) (*bo.OrderNotifyBo, error) {
	now := time.Now()

	info := &model.OrderNotify{
		OrderNo:      req.OrderNo,
		OutRequestNo: req.OutRequestNo,
		Status:       vo.OrderNotifyStatusWait.GetValue(),
		Request:      req.Request,
		NotifyUrl:    req.NotifyUrl,
		CreateTime:   &now,
		UpdateTime:   &now,
	}

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

	return p.ToBo(info), nil
}

func (p *OrderNotifyRepoImpl) Success(ctx context.Context, id uint64, responses string) error {
	now := time.Now()

	res := p.db.DB(ctx).
		Where(model.OrderNotify{
			ID:     id,
			Status: vo.OrderNotifyStatusWait.GetValue(),
		}).
		Updates(model.OrderNotify{
			Status:     vo.OrderNotifyStatusSuccess.GetValue(),
			Responses:  responses,
			UpdateTime: &now,
		})

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

	return nil
}

func (p *OrderNotifyRepoImpl) Fail(ctx context.Context, id uint64, remark string) error {

	if utf8.RuneCountInString(remark) > 100 {
		runes := []rune(remark)
		if len(runes) > 100 {
			remark = string(runes[:100])
		}
	}

	now := time.Now()

	res := p.db.DB(ctx).
		Where(model.OrderNotify{
			ID:     id,
			Status: vo.OrderNotifyStatusWait.GetValue(),
		}).
		Updates(model.OrderNotify{
			Status:     vo.OrderNotifyStatusFail.GetValue(),
			Remark:     remark,
			UpdateTime: &now,
		})

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

	return nil
}
