package debug

import (
	"github.com/pingcap/dbaas/central/db"
	"github.com/pingcap/dbaas/central/db/entity"
	centralModel "github.com/pingcap/dbaas/central/model"
	"github.com/pingcap/dbaas/central/model/admin"
	"github.com/pingcap/dbaas/central/model/admin/grafana"
	runtimemanager "github.com/pingcap/dbaas/central/runtime/manager"
	"github.com/pingcap/errors"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

type Model struct {
	log           *zap.Logger
	grafanaClient *grafana.Client
	runtimes      runtimemanager.Manager
	slowQueryDB   *gorm.DB
}

func NewModel(log *zap.Logger, grafanaClient *grafana.Client, runtimes runtimemanager.Manager, slowQueryDB *gorm.DB) Model {
	return Model{
		log:           log,
		grafanaClient: grafanaClient,
		runtimes:      runtimes,
		slowQueryDB:   slowQueryDB,
	}
}

func (m *Model) ListTenants(name string, id uint64, page, perPage uint32) ([]*admin.Tenant, int64, error) {
	// FIXME: Currently this is completely copied from admin model.
	var (
		tenants []entity.Tenant
		//discounts []entity.GlobalDiscount
		total int64
		err   error
	)

	err = db.Transaction(func(tx *gorm.DB) error {
		qs := entity.NewTenantQuerySet(tx)
		if name != "" {
			qs = qs.NameLike("%" + name + "%")
		}
		if id > 0 {
			qs = qs.IDEq(entity.ID(id))
		}

		if perPage > 0 { //no pagination
			if total, err = qs.Count(); err != nil {
				return errors.Annotate(err, "count tenant error")
			}
			startIndex := centralModel.GetStartIndex(int(page), centralModel.GetSize(int(perPage)))
			qs = qs.Limit(int(perPage)).Offset(startIndex)
		}
		if err := qs.All(&tenants); err != nil {
			return errors.Annotate(err, "fetch tenants failed")
		}
		if perPage <= 0 {
			//no pagination
			total = int64(len(tenants))
		}
		//if err := entity.NewGlobalDiscountQuerySet(tx).All(&discounts); err != nil {
		//	return errors.Annotate(err, "fetch global discount failed")
		//}
		return nil
	})
	if err != nil {
		return nil, 0, err
	}

	var results []*admin.Tenant
	//now := time.Now()
	for _, item := range tenants {
		var tenantDiscount []entity.Discount
		err := db.Transaction(func(tx *gorm.DB) error {
			return entity.NewDiscountQuerySet(tx).TenantIDEq(item.ID).All(&tenantDiscount)
		})
		if err != nil {
			return nil, 0, err
		}
		//hasDiscount, discount, description, startTime, EndTime := centralModel.MergeDiscount(now, discounts, tenantDiscount)
		results = append(results, &admin.Tenant{
			ID:       uint64(item.ID),
			Name:     item.Name,
			Email:    item.Email,
			Country:  item.Country,
			Timezone: item.TimeZone,
			Status:   string(item.Status),
			Plan:     string(item.Plan),
			//BindCreditCardAt:    item.BindCreditCardAt,
			//HasDiscount:         hasDiscount,
			//Discount:            discount,
			//DiscountDescription: description,
			//DiscountStartTime:   startTime,
			//DiscountEndTime:     EndTime,
		})
	}
	return results, total, nil
}
