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/creditriskcontrol"
	"github.com/pingcap/dbaas/billing2/utils/ginutils"
)

type CreditRiskLevelAPI struct{}

// @Summary List All CreditRisk Level
// @Schemes
// @Accept json
// @Produce json
// @Success 200 {object} []forms.CreditRiskLevel
// @Router /credit_risk_levels [get]
func (*CreditRiskLevelAPI) ListAllCreditRiskLevels(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	return (&creditriskcontrol.CreditRiskLevelModel{}).ListAllCreditRiskLevels()
}

type CreditRiskLevelIDStruct struct {
	CreditRiskLevelID uint `uri:"credit_risk_level_id" binding:"required"`
}

func getCreditRiskLevelIDFromURI(c *gin.Context) (uint, error) {
	creditRiskLevelIDStruct := &CreditRiskLevelIDStruct{}
	err := c.ShouldBindUri(creditRiskLevelIDStruct)
	if err != nil {
		return 0, billing_errors.NewInvalidInputError(err)
	}
	return creditRiskLevelIDStruct.CreditRiskLevelID, nil
}

// @Summary Get CreditRisk Level
// @Schemes
// @Accept json
// @Produce json
// @Param credit_risk_level_id path string true "credit_risk_level_id"
// @Success 200 {object} forms.CreditRiskLevel
// @Router /credit_risk_levels/{credit_risk_level_id} [get]
func (*CreditRiskLevelAPI) GetCreditRiskLevelInfo(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	creditRiskLevelID, err := getCreditRiskLevelIDFromURI(c)
	if err != nil {
		return nil, err
	}
	return (&creditriskcontrol.CreditRiskLevelModel{}).GetCreditRiskLevel(creditRiskLevelID)
}

// @Summary Update CreditRisk Level
// @Schemes
// @Accept json
// @Produce json
// @Param credit_risk_level_id path string true "credit_risk_level_id"
// @Param CreditRiskLevel body forms.CreditRiskLevelInput true "CreditRiskLevel"
// @Success 200 {object} forms.OKType
// @Router /credit_risk_levels/{credit_risk_level_id} [put]
func (*CreditRiskLevelAPI) UpdateCreditRiskLevel(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	creditRiskLevelID, err := getCreditRiskLevelIDFromURI(c)
	if err != nil {
		return nil, err
	}
	input := &forms.CreditRiskLevel{}
	err = c.ShouldBindJSON(input)
	if err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	err = (&creditriskcontrol.CreditRiskLevelModel{}).UpdateCreditRiskLevel(creditRiskLevelID, input)
	if err != nil {
		return nil, err
	}
	return forms.OK, nil
}

// @Summary Delete CreditRisk Level
// @Schemes
// @Accept json
// @Produce json
// @Param credit_risk_level_id path string true "credit_risk_level_id"
// @Success 200 {object} forms.OKType
// @Router /credit_risk_levels/{credit_risk_level_id} [delete]
func (*CreditRiskLevelAPI) DeleteCreditRiskLevel(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	creditRiskLevelID, err := getCreditRiskLevelIDFromURI(c)
	if err != nil {
		return nil, err
	}
	err = (&creditriskcontrol.CreditRiskLevelModel{}).DeleteCreditRiskLevel(creditRiskLevelID)
	if err != nil {
		return nil, err
	}
	return forms.OK, nil
}

// @Summary Create CreditRisk Level
// @Schemes
// @Accept json
// @Produce json
// @Param CreditRiskLevel body forms.CreditRiskLevelInput true "CreditRiskLevel"
// @Success 200 {object} forms.CreditRiskLevel
// @Router /credit_risk_levels [post]
func (*CreditRiskLevelAPI) CreateCreditRiskLevel(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	input := &forms.CreditRiskLevel{}
	err := c.ShouldBindJSON(input)
	if err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	return (&creditriskcontrol.CreditRiskLevelModel{}).CreateCreditRiskLevel(input)
}

// @Summary Get Tenant CreditRisk Level
// @Schemes
// @Accept json
// @Produce json
// @Param tenant_id path string true "tenant_id"
// @Success 200 {object} forms.CreditRiskLevel
// @Router /tenants/{tenant_id}/credit_risk_level [get]
func (*CreditRiskLevelAPI) GetTenantCreditRiskLevel(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	tenantID, err := getTenantIDFromURI(c)
	if err != nil {
		return nil, err
	}
	return (&creditriskcontrol.CreditRiskLevelModel{}).GetTenantCreditRiskLevel(tenantID)
}

// @Summary Update Tenant CreditRisk Level
// @Schemes
// @Accept json
// @Produce json
// @Param tenant_id path string true "tenant_id"
// @Param CreditRiskLevel body forms.CreditRiskLevelIDInput true "CreditRiskLevel"
// @Success 200 {object} forms.OKType
// @Router /tenants/{tenant_id}/credit_risk_level [put]
func (*CreditRiskLevelAPI) UpdateTenantCreditRiskLevel(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	tenantID, err := getTenantIDFromURI(c)
	if err != nil {
		return nil, err
	}
	input := &forms.CreditRiskLevelIDInput{}
	err = c.ShouldBindJSON(input)
	if err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	err = (&creditriskcontrol.CreditRiskLevelModel{}).SetTenantCreditRiskLevel(tenantID, input.CreditRiskLevelID)
	if err != nil {
		return nil, err
	}
	return forms.OK, nil
}

func InitializeCreditRiskLevelRouter(router ginutils.MyRoute) {
	s := &CreditRiskLevelAPI{}
	_ = s
	router.HandleWithError("GET", "/credit_risk_levels", s.ListAllCreditRiskLevels)
	router.HandleWithError("POST", "/credit_risk_levels", s.CreateCreditRiskLevel)
	router.HandleWithError("GET", "/credit_risk_levels/:credit_risk_level_id", s.GetCreditRiskLevelInfo)
	router.HandleWithError("PUT", "/credit_risk_levels/:credit_risk_level_id", s.UpdateCreditRiskLevel)
	router.HandleWithError("DELETE", "/credit_risk_levels/:credit_risk_level_id", s.DeleteCreditRiskLevel)
	router.HandleWithError("GET", "/tenants/:tenant_id/credit_risk_level", s.GetTenantCreditRiskLevel)
	router.HandleWithError("PUT", "/tenants/:tenant_id/credit_risk_level", s.UpdateTenantCreditRiskLevel)

}
