package api

import (
	"github.com/gin-gonic/gin"
	"github.com/pingcap/dbaas/billing2/billing_errors"
	"github.com/pingcap/dbaas/billing2/forms"
	"github.com/pingcap/dbaas/billing2/model/control"
	"github.com/pingcap/dbaas/billing2/utils/ginutils"
	"github.com/pingcap/dbaas/billing2/utils/log"
	"go.uber.org/zap"
)

type ControlModel struct {
}

// @Summary Billing Action Check
// @Schemes
// @Accept json
// @Produce json
// @Param tenant_id path string true "tenant_id"
// @Param input body forms.BillingActionInfo true "BillingActionInfo"
// @Success 200 {object} forms.BillingActionCheckResult
// @Router /tenants/{tenant_id}/billing_action_check [post]
func (s *ControlModel) BillingActionCheck(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	model := control.Model{}
	tenantID, err := getTenantIDFromURI(c)
	if err != nil {
		return nil, err
	}
	var action forms.BillingActionInfo
	err = c.ShouldBindJSON(&action)
	if err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	log.Info("start to check billing action", zap.Uint("tenantID", tenantID), zap.Any("action", action))
	ret, err := model.BillingActionCheck(tenantID, &action)
	if err != nil {
		log.Error("failed to check billing action", zap.Error(err), zap.Uint("tenantID", tenantID), zap.Any("action", action))
	}
	log.Info("success to check billing action", zap.Any("result", ret), zap.Uint("tenantID", tenantID), zap.Any("action", action))
	return ret, nil
}

// @Summary Billing Action Check
// @Schemes
// @Accept json
// @Produce json
// @Param tenant_id path string true "tenant_id"
// @Param input body forms.BillingActionCheckBatchInput true "BillingActionCheckBatchInput"
// @Success 200 {object} forms.BillingActionCheckBatchOutput
// @Router /tenants/{tenant_id}/billing_action_check/_batch [post]
func (s *ControlModel) BillingActionCheckBatch(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	model := control.Model{}
	tenantID, err := getTenantIDFromURI(c)
	if err != nil {
		return nil, err
	}
	var actionsQuery forms.BillingActionCheckBatchInput
	err = c.ShouldBindJSON(&actionsQuery)
	if err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	log.Info("start to check billing actions", zap.Uint("tenantID", tenantID), zap.Any("action", actionsQuery))
	results := make([]*forms.BillingActionCheckResult, len(actionsQuery.Actions))
	for i, action := range actionsQuery.Actions {
		results[i], err = model.BillingActionCheck(tenantID, action)
		if err != nil {
			log.Error("failed to check billing action", zap.Error(err), zap.Uint("tenantID", tenantID), zap.Any("action", action))
			return nil, err
		}
	}
	ret := forms.BillingActionCheckBatchOutput{Results: results}
	log.Info("success to check billing actions", zap.Any("result", ret), zap.Uint("tenantID", tenantID), zap.Any("action", actionsQuery))
	return ret, nil
}

func InitializeControlRouter(router ginutils.MyRoute) {
	s := &ControlModel{}
	router.HandleWithError("POST", "/tenants/:tenant_id/billing_action_check", s.BillingActionCheck)
	router.HandleWithError("POST", "/tenants/:tenant_id/billing_action_check/_batch", s.BillingActionCheckBatch)
}
