package impl

import (
	"context"

	"github.com/tidbcloud/dataflow-service/app/repo/crrf"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/pkgv2/db"
)

var _ crrf.CRRFSettingRepo = (*crrfSettingRepoImpl)(nil)

type crrfSettingRepoImpl struct {
	dbProvider db.Provider
}

// NewCRRFSettingRepo creates a new CRRFSettingRepo.
func NewCRRFSettingRepo(provider db.Provider) crrf.CRRFSettingRepo {
	return &crrfSettingRepoImpl{dbProvider: provider}
}

func (r *crrfSettingRepoImpl) ListByFilter(ctx context.Context, filter crrf.CRRFSettingFilter) ([]*entity.CRRFSetting, bizerr.BizError) {
	rdb := r.dbProvider.ReadDB(ctx)
	query := rdb.Model(&entity.CRRFSetting{})
	if filter != nil {
		query = filter(query)
	}
	var settings []*entity.CRRFSetting
	if err := query.Find(&settings).Error; err != nil {
		return nil, bizerr.WrapGormError(err, "list crrf_settings by filter")
	}
	return settings, nil
}

func (r *crrfSettingRepoImpl) GetByClusterID(ctx context.Context, clusterID uint64) (*entity.CRRFSetting, bizerr.BizError) {
	rdb := r.dbProvider.ReadDB(ctx)
	setting := new(entity.CRRFSetting)
	if err := rdb.Where("cluster_id = ?", clusterID).First(setting).Error; err != nil {
		return nil, bizerr.WrapGormError(err, "get crrf_setting by cluster_id %d", clusterID)
	}
	return setting, nil
}

func (r *crrfSettingRepoImpl) Save(ctx context.Context, setting *entity.CRRFSetting) bizerr.BizError {
	wdb := r.dbProvider.WriteDB(ctx)
	if err := entity.SaveWithVersioning(wdb, setting); err != nil {
		return err.Chain("save crrf_setting with versioning, cluster %d", setting.ClusterID)
	}
	return nil
}

func (r *crrfSettingRepoImpl) DeleteByClusterID(ctx context.Context, clusterID uint64) bizerr.BizError {
	wdb := r.dbProvider.WriteDB(ctx)
	if err := wdb.Where("cluster_id = ?", clusterID).Delete(&entity.CRRFSetting{}).Error; err != nil {
		return bizerr.WrapGormError(err, "delete crrf_setting by cluster_id %d", clusterID)
	}
	return nil
}
