package hook_impl

import (
	"github.com/tidbcloud/dataflow-service/app/event_bus/publisher/center"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	"github.com/tidbcloud/dataflow-service/pkg/log"
	"github.com/tidbcloud/eventbus-datastruct/event"
	"gorm.io/gorm"
)

const StatusChangedKey = "isStatusChanged"

func BaseBeforeSave(
	tx *gorm.DB,
	value interface{},
	isNewlyCreated func(tx *gorm.DB, v interface{}) bool,
	isStatusChanged func(tx *gorm.DB, v interface{}) bool,
) {
	if isNewlyCreated(tx, value) || isStatusChanged(tx, value) {
		setStatusChanged(tx)
	}
}

func BaseAfterSave(
	tx *gorm.DB, value interface{},
	dataConvert func(tx *gorm.DB, value interface{}) *event.DisplayEvent,
) {
	if checkStatusChanged(tx) {
		center.GetEventCenterPublisher().PublishAsync(dataConvert(tx, value))
	}
}

func setStatusChanged(tx *gorm.DB) {
	tx.Statement.Settings.Store(StatusChangedKey, true)
}

func checkStatusChanged(tx *gorm.DB) bool {
	_, ok := tx.Get(StatusChangedKey)
	return ok
}

func isNewlyCreated(tx *gorm.DB, v interface{}) bool {
	logger := log.GetLogger(tx.Statement.Context)
	base, ok := v.(entity.IdAndVersioning)
	if !ok {
		logger.Warn("value is not impl interface of IdAndVersioning")
		return false
	}

	if base.GetID() == 0 {
		return true
	}

	return false
}
