package server

import (
	"context"
	"errors"

	"github.com/tidbcloud/cluster-service-ng/domain/entity"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"gorm.io/gorm"
)

func (s *serverImpl) GetScaleOperation(ctx context.Context, sharedPoolID, scaleOperationID string) (*entity.ScaleOperation, error) {
	if sharedPoolID == "" {
		return nil, status.Error(codes.InvalidArgument, "shared_pool_id is required")
	}
	if scaleOperationID == "" {
		return nil, status.Error(codes.InvalidArgument, "scale_operation_id is required")
	}
	if s.scaleOperationCfg == nil || !s.scaleOperationCfg.Enabled {
		return nil, scaleOperationDisabledError()
	}
	operation, err := s.scaleOperationRepo.LoadByID(ctx, sharedPoolID, scaleOperationID, false)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, status.Error(codes.NotFound, "scale operation not found")
		}
		tilog.Error(ctx, "failed to load scale operation",
			zap.String("sharedPoolId", sharedPoolID), zap.String("scaleOperationId", scaleOperationID), zap.Error(err))
		return nil, status.Error(codes.Internal, "failed to get scale operation")
	}
	return operation, nil
}

// CancelScaleOperation is a gated stub in this PR: it validates the operation
// exists and the feature is enabled, then returns Unimplemented. Real cancel
// (state transition + compensation worker) lands with M1's cancel PR.
func (s *serverImpl) CancelScaleOperation(ctx context.Context, sharedPoolID, scaleOperationID, _ string) (*entity.ScaleOperation, error) {
	if sharedPoolID == "" {
		return nil, status.Error(codes.InvalidArgument, "shared_pool_id is required")
	}
	if scaleOperationID == "" {
		return nil, status.Error(codes.InvalidArgument, "scale_operation_id is required")
	}
	if s.scaleOperationCfg == nil || !s.scaleOperationCfg.Enabled {
		return nil, scaleOperationDisabledError()
	}
	if _, err := s.GetScaleOperation(ctx, sharedPoolID, scaleOperationID); err != nil {
		return nil, err
	}
	return nil, status.Error(codes.Unimplemented, "scale operation cancel is not implemented")
}

func scaleOperationDisabledError() error {
	return status.Error(codes.FailedPrecondition, "scale operation is disabled")
}
