package git

import (
	"context"
	"fmt"

	"github.com/tidbcloud/ecosystem-service/internal/service/grpc/mgmt"
	gitDB "github.com/tidbcloud/ecosystem-service/internal/storage/db/git"
	"github.com/tidbcloud/pkgv2/logid"
	globalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/serverless/v1"
	mgmtapi "github.com/tidbcloud/tidb-management-service/api/spec/tidb_mgmt_service/v1"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
)

type GitCronJob struct {
	mgmtSvc               mgmt.MgmtSvc
	tiDBGitIntegrationDAO gitDB.TiDBGitIntegrationDAO
}

func NewGitCronJob(mgmtSvc mgmt.MgmtSvc, tiDBGitIntegrationDAO gitDB.TiDBGitIntegrationDAO) *GitCronJob {
	return &GitCronJob{
		mgmtSvc:               mgmtSvc,
		tiDBGitIntegrationDAO: tiDBGitIntegrationDAO,
	}
}

func (g *GitCronJob) AutoClean() {
	ctx := context.Background()
	logID := logid.GenLogid()
	ctx = logid.WithLogid(ctx, logID)
	tilog.Info(ctx, "Start to clean git connections")

	gitConnections, err := g.tiDBGitIntegrationDAO.ListAllGitIntegrations(ctx)
	if err != nil {
		tilog.Error(ctx, "Failed to list all TiDB cluster ids in git integration", zap.Error(err))
		return
	}
	if len(gitConnections) == 0 {
		tilog.Warn(ctx, "No clusters found")
		return
	}

	clusterIDs := make([]uint64, 0, len(gitConnections))
	for _, gitConnection := range gitConnections {
		clusterIDs = append(clusterIDs, gitConnection.TiDBClusterID)
	}

	clusters, err := g.mgmtSvc.ListClusters(ctx, clusterIDs, mgmtapi.ClusterFilter_CLUSTER_VIEW_BASIC)
	if err != nil {
		tilog.Error(ctx, "Failed to get clusters in mgmt-svc", zap.Error(err))
		return
	}

	var clusterIDsToClean []uint64
	for _, id := range clusterIDs {
		if cluster, ok := clusters[id]; ok {
			if cluster.GetServerlessCluster().GetUserStatus() == globalserverlessv1.UserClusterStatus_USER_CLUSTER_STATUS_DELETED {
				clusterIDsToClean = append(clusterIDsToClean, id)
				tilog.Info(ctx, "Cluster is deleted", zap.Uint64("cluster_id", id))
			}
		} else {
			tilog.Warn(ctx, "Cluster not found in mgmt-svc result", zap.Uint64("cluster_id", id))
		}
	}

	if len(clusterIDsToClean) == 0 {
		tilog.Info(ctx, "No clusters to clean")
		return
	}
	tilog.Info(ctx, "Start to delete git connection", zap.Any("clusterIDsToClean", clusterIDsToClean))

	for _, clusterID := range clusterIDsToClean {
		_, err := g.tiDBGitIntegrationDAO.DeleteGitIntegrationByClusterID(ctx, clusterID)
		if err != nil {
			tilog.Error(ctx, fmt.Sprintf("failed to delete git connection with clusterId:%d", clusterID), zap.Error(err))
			continue
		}
	}

	tilog.Info(ctx, "Delete connections success", zap.Any("cleaned cluster", clusterIDsToClean))
}
