package byocvpcpeering

import (
	"context"

	"github.com/tidbcloud/pkgv2/db"
	"go.opentelemetry.io/otel"

	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	repo "github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/byocvpcpeering"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/infra/repoimpl/schema"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

var tracer = otel.Tracer("infra.byocvpcpeering")

func NewByocVpcPeeringRepo(provider db.Provider) repo.Repo {
	return &repoImpl{provider: provider}
}

type repoImpl struct {
	provider db.Provider
}

func (r *repoImpl) GetByClusterID(ctx context.Context, clusterID uint64) (*entity.VpcPeeringAllowlistSetting, bizerr.BizError) {
	ctx, span := tracer.Start(ctx, "byocvpcpeering.GetByClusterID")
	defer span.End()

	var setting schema.ByocVpcPeeringAllowlistSetting
	if rawErr := r.provider.ReadDB(ctx).Model(&schema.ByocVpcPeeringAllowlistSetting{}).
		Where("`cluster_id` = ?", clusterID).
		First(&setting).Error; rawErr != nil {
		return nil, bizerr.WrapGormError(rawErr, "load byoc vpc peering allowlist setting")
	}
	return modelToEn(&setting), nil
}

func (r *repoImpl) Save(ctx context.Context, setting *entity.VpcPeeringAllowlistSetting) bizerr.BizError {
	ctx, span := tracer.Start(ctx, "byocvpcpeering.Save")
	defer span.End()

	model := enToModel(setting)
	wdb := r.provider.WriteDB(ctx)

	var existing schema.ByocVpcPeeringAllowlistSetting
	if rawErr := wdb.Model(&schema.ByocVpcPeeringAllowlistSetting{}).
		Where("`cluster_id` = ?", setting.GetClusterId()).
		First(&existing).Error; rawErr != nil {
		err := bizerr.WrapGormError(rawErr, "load byoc vpc peering allowlist setting")
		if err.ErrCode() != bizerr.ErrCodeRecordNotFound {
			return err
		}
		if rawErr := wdb.Create(model).Error; rawErr != nil {
			return bizerr.WrapGormError(rawErr, "create byoc vpc peering allowlist setting")
		}
		return nil
	}

	model.ID = existing.ID
	if rawErr := wdb.Omit("created_at").Save(model).Error; rawErr != nil {
		return bizerr.WrapGormError(rawErr, "save byoc vpc peering allowlist setting")
	}
	return nil
}

func (r *repoImpl) DeleteByClusterID(ctx context.Context, clusterID uint64) bizerr.BizError {
	if err := r.provider.WriteDB(ctx).
		Where("`cluster_id` = ?", clusterID).
		Delete(&schema.ByocVpcPeeringAllowlistSetting{}).Error; err != nil {
		return bizerr.WrapGormError(err, "delete byoc vpc peering allowlist setting")
	}
	return nil
}
