package restore

import (
	"context"
	"time"

	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	"github.com/tidbcloud/pkgv2/db"
	"gorm.io/gorm"
)

type ServerlessRestoreRepoImpl struct {
	dbProvider db.Provider
}

var _ ServerlessRestoreRepo = (*ServerlessRestoreRepoImpl)(nil)

func NewServerlessRestoreRepo(dbProvider db.Provider) ServerlessRestoreRepo {
	return &ServerlessRestoreRepoImpl{
		dbProvider: dbProvider,
	}
}

func (r *ServerlessRestoreRepoImpl) Add(ctx context.Context, restore *entity.ServerlessRestore) error {
	wdb := r.dbProvider.WriteDB(ctx)
	if result := wdb.Create(restore); result.Error != nil {
		return result.Error
	}
	return nil
}

func (r *ServerlessRestoreRepoImpl) Save(ctx context.Context, restore *entity.ServerlessRestore) error {
	wdb := r.dbProvider.WriteDB(ctx)
	now := time.Now()
	restore.UpdatedAt = &now
	if result := wdb.Save(restore); result.Error != nil {
		return result.Error
	}
	return nil
}

func (r *ServerlessRestoreRepoImpl) Load(ctx context.Context, id entity.ID) (*entity.ServerlessRestore, error) {
	rdb := r.dbProvider.ReadDB(ctx)
	restore := new(entity.ServerlessRestore)
	if err := entity.NewServerlessRestoreQuerySet(rdb).IDEq(id).One(restore); err != nil {
		return nil, err
	}
	return restore, nil
}

func (r *ServerlessRestoreRepoImpl) GetByFilter(
	ctx context.Context, filter *ServerlessRestoreFilter,
) (*entity.ServerlessRestore, error) {
	rdb := r.dbProvider.ReadDB(ctx)
	tx := r.buildTxServerlessRestoreFilter(rdb, filter)
	restore := new(entity.ServerlessRestore)
	if result := tx.First(restore); result.Error != nil {
		return nil, result.Error
	}
	return restore, nil
}

func (r *ServerlessRestoreRepoImpl) ListByFilter(
	ctx context.Context, filter *ServerlessRestoreFilter,
) ([]*entity.ServerlessRestore, error) {
	rdb := r.dbProvider.ReadDB(ctx)
	tx := r.buildTxServerlessRestoreFilter(rdb, filter)
	var restores []*entity.ServerlessRestore
	if result := tx.Find(&restores); result.Error != nil {
		return nil, result.Error
	}
	return restores, nil
}

func (r *ServerlessRestoreRepoImpl) buildTxServerlessRestoreFilter(
	tx *gorm.DB, filter *ServerlessRestoreFilter,
) *gorm.DB {
	if filter.ClusterID != nil {
		tx = tx.Where("cluster_id = ?", *filter.ClusterID)
	}
	if filter.UserClusterBackupID != nil {
		tx = tx.Where("user_cluster_backup_id = ?", *filter.UserClusterBackupID)
	}
	if len(filter.Statuses) > 0 {
		tx = tx.Where("status in ?", filter.Statuses)
	}
	if filter.OrderByCreateTime != nil {
		if *filter.OrderByCreateTime == OrderByAsc {
			tx = tx.Order("created_at ASC")
		} else if *filter.OrderByCreateTime == OrderByDesc {
			tx = tx.Order("created_at DESC")
		}
	}
	if filter.Limit != nil {
		tx = tx.Limit(*filter.Limit)
	}
	return tx
}
