package admin

import (
	"context"
	"fmt"
	"time"

	"github.com/pingcap/dbaas/central/db"
	"github.com/pingcap/dbaas/central/db/dbutil"
	"github.com/pingcap/dbaas/central/db/entity"
	"github.com/pingcap/dbaas/pkg/tidb/component"
	"github.com/pingcap/errcode"
	"github.com/tidbcloud/idl/pbgen/proto/central"
	"gorm.io/gorm"
)

type TenantCluster struct {
	Id          entity.ID
	Name        string
	Provider    string
	Region      string
	Profile     string // FIXME: this filed seems not to be used now
	Version     string
	CreateTime  time.Time
	Resources   []component.Resources
	Status      central.Cluster_Status
	ProjectID   entity.ID
	ProjectName string
}

type ClusterLifecycle struct {
	ID        uint64
	ProjectID uint64
	CreatedAt int64
	DeletedAt int64
}

func (m UserContext) DeleteTenantCluster(tenantID, clusterID uint64) error {
	return db.Transaction(func(tx *gorm.DB) error {
		var err error
		var cluster entity.Cluster
		if cluster, err = dbutil.GetCluster(tx, entity.ID(clusterID)); err != nil {
			return err
		}
		if cluster.TenantID.Uint64() != tenantID {
			return errcode.NewForbiddenErr(fmt.Errorf("cluster %d does not belong to tenant %d", clusterID, tenantID))
		}
		if err := dbutil.DeleteCluster(context.Background(), tx, entity.ID(clusterID)); err != nil {
			return err
		}
		return dbutil.AddAccessLogNow(tx, m.tenantAndUser.TenantID, m.tenantAndUser.Email, fmt.Sprintf("delete cluster %d for tenant %d", clusterID, tenantID))
	})
}

func (m UserContext) ListTenantClusterLifeCycle(tenantID uint64, start, end int64) ([]ClusterLifecycle, error) {
	var (
		clusters []entity.Cluster
		err      error
	)
	if err = db.Transaction(func(tx *gorm.DB) error {
		clusters, err = dbutil.GetClusterMatchTimeRange(tx, entity.ID(tenantID), start, end)
		return err
	}); err != nil {
		return nil, err
	}
	var clf []ClusterLifecycle
	for _, item := range clusters {
		var deletedAt int64 = 0
		if item.DeletedTime != nil {
			deletedAt = item.DeletedTime.Unix()
		}
		clf = append(clf, ClusterLifecycle{
			ID:        item.ID.Uint64(),
			ProjectID: item.ProjectID.Uint64(),
			CreatedAt: item.CreatedAt.Unix(),
			DeletedAt: deletedAt,
		})
	}
	return clf, nil
}
