package service

import (
	"context"
	"time"

	scalerpb "github.com/tidbcloud/aws-shared-provider/pkg/tidbworker/proto/scaler"
	"github.com/tidbcloud/aws-shared-provider/pkg/tidbworker/schema/gcv2"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

func (s *ScalerService) RegisterGCV2(
	ctx context.Context,
	request *scalerpb.RegisterGCV2Request,
) (*scalerpb.Response, error) {
	if request == nil || request.GetHeader() == nil {
		return scalerResponse(ErrBadRequest), nil
	}

	err := s.GetDB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		err := tx.Model(&gcv2.Task{}).
			Where("keyspace_name = ?", request.GetHeader().GetKeyspaceName()).
			Where("last_gc_run_ts <= ?", request.GetSafePoint()).
			Update("state", gcv2.StateDone).Error
		if err != nil {
			return err
		}

		return tx.Clauses(clause.OnConflict{
			DoNothing: true,
		}).Create(&gcv2.Task{
			KeyspaceName:  request.GetHeader().GetKeyspaceName(),
			TidbPool:      request.GetHeader().GetTidbPool(),
			LastGCRunTime: time.Now().Unix(),
			LastGCRunTs:   request.GetSafePoint(),
			GCLifeTime:    request.GetGcLifeTime(),
			State:         gcv2.StatePending,
		}).Error
	})
	return scalerResponse(err), nil
}

func (s *ScalerService) RecycleGCV2(
	ctx context.Context,
	request *scalerpb.RecycleGCV2Request,
) (*scalerpb.Response, error) {
	if request == nil || request.GetHeader() == nil {
		return scalerResponse(ErrBadRequest), nil
	}

	err := s.GetDB().WithContext(ctx).Model(&gcv2.Task{}).
		Where("keyspace_name = ?", request.GetHeader().GetKeyspaceName()).
		Where("last_gc_run_ts < ?", request.GetSafePoint()).
		Update("state", gcv2.StateDone).
		Error
	return scalerResponse(err), nil
}

func (s *ScalerService) UpdateGCLifeTime(
	ctx context.Context,
	request *scalerpb.UpdateGCLifeTimeRequest,
) (*scalerpb.Response, error) {
	if request == nil || request.GetHeader() == nil {
		return scalerResponse(ErrBadRequest), nil
	}

	err := s.GetDB().WithContext(ctx).Model(&gcv2.Task{}).
		Where("keyspace_name = ?", request.GetHeader().GetKeyspaceName()).
		Update("gc_life_time", request.GetGcLifeTime()).
		Error
	return scalerResponse(err), nil
}
