package model

import (
	"strconv"

	"github.com/juju/errors"
	"github.com/tidbcloud/debug_portal/db"
	"github.com/tidbcloud/debug_portal/db/entity"
	"github.com/tidbcloud/debug_portal/model/admin"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

type Model struct {
	log           *zap.Logger
	grafanaClient *GrafanaClient
	//slowQueryDB   *gorm.DB
}

func NewModel(log *zap.Logger, grafanaClient *GrafanaClient) Model {
	return Model{
		log:           log,
		grafanaClient: grafanaClient,
		//slowQueryDB:   slowQueryDB,
	}
}

func (m *Model) ListTenants(name string, id uint64, email string, status []string, 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).OrderDescByCreatedAt()

		if name != "" {
			qs = entity.NewTenantQuerySet(qs.GetDB().Where("LOWER(CONVERT(name USING utf8)) LIKE LOWER(?)", "%"+name+"%"))
		}
		if id > 0 {
			qs = qs.IDEq(entity.ID(id))
		}
		if email != "" {
			qs = qs.EmailLike("%" + email + "%")
		}
		if len(status) > 0 {
			qs = entity.NewTenantQuerySet(qs.GetDB().Where("status IN (?)", status))
		}

		if perPage > 0 { //no pagination
			if total, err = qs.Count(); err != nil {
				return errors.Annotate(err, "count tenant error")
			}
			startIndex := GetStartIndex(int(page), 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
		}
		timezone, err := strconv.Atoi(item.TimeZone)
		if err != nil {
			return nil, 0, err
		}
		//hasDiscount, discount, description, startTime, EndTime := centralModel.MergeDiscount(now, discounts, tenantDiscount)
		results = append(results, &admin.Tenant{
			ID:       item.ID,
			Name:     item.Name,
			Email:    item.Email,
			Country:  item.Country,
			Timezone: int32(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
}

func GetStartIndex(page int, itemsPerPage int) int {
	if page <= 0 {
		page = 1
	}
	return (page - 1) * GetSize(itemsPerPage)
}

func GetSize(itemsPerPage int) int {
	if itemsPerPage <= 0 {
		itemsPerPage = 10
	}
	return itemsPerPage
}
