package biz

import (
	"context"
	"fmt"
	err2 "voucher/api/err"
	"voucher/internal/biz/bo"
	"voucher/internal/biz/vo"
	"voucher/internal/pkg/lock"
)

func (this *VoucherBiz) RegisterTag(ctx context.Context, id int32) error {

	stock, err := this.ProductRepo.GetById(ctx, id)
	if err != nil {
		return err
	}

	wxResp, err := this.WechatCpnRepo.QueryProduct(ctx, stock.MchId, stock.BatchNo)
	if err != nil {
		return err
	}

	if err = this.ProductRepo.UpdateByWxResp(ctx, stock.ID, this.WxResp(wxResp)); err != nil {
		return err
	}

	if this.IsNotifyRegisterTag(stock) {
		if err = this.registerNotifyTag(ctx, stock.MchId, stock.BatchNo); err != nil {
			return err
		}
	}

	_ = this.ProductRepo.DelCacheByProductNo(ctx, stock.ProductNo)
	_, err = this.ProductRepo.GetByProductNo(ctx, stock.ProductNo)

	return err
}

func (this *VoucherBiz) IsNotifyRegisterTag(product *bo.ProductBo) bool {
	for _, subject := range this.bc.WechatSubject {
		if subject.MchID == product.MchId {
			return false
		}
	}
	return true
}

func (this *VoucherBiz) registerNotifyTag(ctx context.Context, stockCreatorMchID, stockID string) error {

	cl := vo.WechatNotifyRegisterTagCacheLockKey.BuildCache([]string{this.bc.WechatNotifyMQ.Tag, stockCreatorMchID, stockID})

	return lock.NewMutex(this.rdb.Rdb, cl.TTL).Lock(ctx, cl.Key, func(ctx context.Context) error {

		wechatNotifyTag, err3 := this.WechatNotifyRegisterTagRepo.GetByStockIdAndMchId(ctx, stockCreatorMchID, stockID)
		if err3 != nil && !err2.IsDbNotFound(err3) {
			return err3
		}

		if wechatNotifyTag != nil {
			if wechatNotifyTag.Tag != this.bc.WechatNotifyMQ.Tag {
				return fmt.Errorf("tag不一致，请检查tag配置:%s", wechatNotifyTag.Tag)
			}

			if wechatNotifyTag.Status.IsSuccess() {
				return nil
			}
		} else {
			wechatNotifyTag, err3 = this.createRegisterTag(ctx, stockCreatorMchID, stockID)
			if err3 != nil {
				return err3
			}
		}

		if err := this.WechatCpnRepo.RegisterNotifyTag(ctx, stockID); err != nil {
			return this.WechatNotifyRegisterTagRepo.Fail(ctx, wechatNotifyTag.ID, err.Error())
		}

		return this.WechatNotifyRegisterTagRepo.Success(ctx, wechatNotifyTag.ID)
	})
}

func (this *VoucherBiz) createRegisterTag(ctx context.Context, stockCreatorMchID, stockID string) (*bo.WechatNotifyRegisterTagBo, error) {
	return this.WechatNotifyRegisterTagRepo.Create(ctx, &bo.WechatNotifyRegisterTagBo{
		StockID:           stockID,
		StockCreatorMchID: stockCreatorMchID,
		Tag:               this.bc.WechatNotifyMQ.Tag,
	})
}
