package server

import (
	"context"
	"fmt"

	apiv1 "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"
	"github.com/tidbcloud/cluster-service-ng/domain/server/br"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type GetManualBackupRestorePostActionsInput struct {
	*apiv1.GetManualBackupRestorePostActionsRequest
}

type GetManualBackupRestorePostActionsOutput struct {
	*apiv1.GetManualBackupRestorePostActionsResponse
}

func (s *serverImpl) GetManualBackupRestorePostActions(ctx context.Context, input *GetManualBackupRestorePostActionsInput) (*GetManualBackupRestorePostActionsOutput, error) {
	restore, err := s.manualBackupRestoreRepo.Load(ctx, input.RestoreId, false)
	if err != nil {
		if status.Code(err) == codes.NotFound {
			return nil, status.Errorf(codes.NotFound, "manual backup restore not found")
		}
		tilog.Error(ctx, "failed to load manual backup restore record", zap.Error(err), zap.String("restoreId", input.RestoreId))
		return nil, fmt.Errorf("failed to load manual backup restore record: %w", err)
	}

	if restore.SourceClusterID != input.SourceClusterId || restore.SourceBackupID != input.BackupId {
		tilog.Warn(ctx, "manual backup restore scope mismatch",
			zap.String("restoreId", input.RestoreId),
			zap.String("requestedSourceClusterId", input.SourceClusterId),
			zap.String("requestedBackupId", input.BackupId),
			zap.String("restoreSourceClusterId", restore.SourceClusterID),
			zap.String("restoreSourceBackupId", restore.SourceBackupID),
		)
		return nil, status.Errorf(codes.NotFound, "manual backup restore not found")
	}

	resp := &GetManualBackupRestorePostActionsOutput{GetManualBackupRestorePostActionsResponse: &apiv1.GetManualBackupRestorePostActionsResponse{}}
	if restore.SourceSharedPoolID == restore.TargetSharedPoolID {
		return resp, nil
	}

	result, err := br.BuildGlobalCompensateResult(ctx, s.sharedPoolRepo, restore.TargetSharedPoolID)
	if err != nil {
		return nil, err
	}
	resp.ExecSql = result.SQL
	resp.CloudStorageUri = result.CloudStorageURI
	return resp, nil
}
