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

// @Summary Add SKU Groups
// @Schemes
// @Accept json
// @Produce json
// @Param SKUGroup body forms.SKUGroup true "SKUGroup"
// @Success 200 {object} forms.SKUGroup
// @Router /sku_groups [post]
func (s *API) AddSKUGroup(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	uriForm := &forms.SKUGroup{}

	if err := c.ShouldBindJSON(&uriForm); err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}

	model := &billing.SKUGroupModel{}
	res, err := model.CreateGroup(uriForm)
	if err != nil {
		return nil, err
	}
	return res, nil
}

// @Summary Get SKU Groups
// @Schemes
// @Accept json
// @Produce json
// @Success 200 {object}  []forms.SKUGroup
// @Router /sku_groups [get]
func (s *API) GetSKUGroupList(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	model := &billing.SKUGroupModel{}
	res, err := model.GetSKUGroupList()
	if err != nil {
		return nil, err
	}
	return res, nil
}

type GroupIDURIForm struct {
	GroupID uint `uri:"group_id"`
}

type CategoryURIForm struct {
	Category string `uri:"category"`
}

// @Summary Get SKU Group
// @Schemes
// @Accept json
// @Produce json
// @Param group_id path string true "group_id"
// @Success 200 {object}  []forms.SKUGroup
// @Router /sku_groups/{group_id} [get]
func (s *API) GetSKUGroup(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	uriForm := &GroupIDURIForm{}

	if err := c.ShouldBindUri(&uriForm); err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}

	model := &billing.SKUGroupModel{}
	res, err := model.GetSKUGroup(uriForm.GroupID)
	if err != nil {
		return nil, err
	}
	return res, nil
}

// @Summary Update SKU Group
// @Schemes
// @Accept json
// @Produce json
// @Param SKUGroup body forms.SKUGroup true "SKUGroup"
// @Success 200 {object}  []forms.SKUGroup
// @Router /sku_groups/{group_id} [put]
func (s *API) UpdateSKUGroup(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	uriForm := GroupIDURIForm{}
	bodyForm := &forms.SKUGroup{}

	if err := c.ShouldBindUri(&uriForm); err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	if err := c.ShouldBindJSON(&bodyForm); err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	model := &billing.SKUGroupModel{}
	res, err := model.UpdateSKUGroup(uriForm.GroupID, bodyForm)
	if err != nil {
		return nil, err
	}
	return res, nil
}

// @Summary Update SKU Group
// @Schemes
// @Accept json
// @Produce json
// @Param group_id path string true "group_id"
// @Success 200 {object} forms.OKType
// @Router /sku_groups/{group_id} [DELETE]
func (s *API) DeleteSKUGroup(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	uriForm := &GroupIDURIForm{}

	if err := c.ShouldBindUri(&uriForm); err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}

	model := &billing.SKUGroupModel{}
	err := model.DeleteSKUGroup(uriForm.GroupID)
	if err != nil {
		return nil, err
	}
	return forms.OK, nil
}

// @Summary Get Category View
// @Schemes
// @Accept json
// @Produce json
// @Success 200 {object} []forms.CategoryNode
// @Router /sku_groups/category [GET]
func (s *API) GetCategoryView(c *gin.Context) (ginutils.HandlerFuncResult, error) {

	model := &costexplorer.CostExplorerModel{}
	return model.GetAllCategoryViewForOps(nil), nil

}

// @Summary Add SKU Group Category
// @Schemes
// @Accept json
// @Produce json
// @Param CategoryItemShow body forms.CategoryItemShow true "CategoryItemShow"
// @Success 200 {object} forms.CategoryItemShow
// @Router /sku_groups/category [POST]
func (s *API) AddCategoryItemShow(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	bodyForm := &forms.CategoryItemShow{}
	if err := c.ShouldBindJSON(bodyForm); err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	model := &billing.SKUGroupModel{}
	return model.AddCategoryItemShow(bodyForm)
}

// @Summary Get SKU Group Category
// @Schemes
// @Accept json
// @Produce json
// @Param category path string true "category"
// @Success 200 {object} forms.CategoryItemShow
// @Router /sku_groups/category/{category} [GET]
func (s *API) GetCategoryItemShow(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	uriForm := &CategoryURIForm{}
	if err := c.ShouldBindUri(uriForm); err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	model := &billing.SKUGroupModel{}
	return model.GetCategoryItemShow(uriForm.Category)
}

// @Summary Update SKU Group Category
// @Schemes
// @Accept json
// @Produce json
// @Param category path string true "category"
// @Param CategoryItemShow body forms.CategoryItemShow true "CategoryItemShow"
// @Success 200 {object} forms.CategoryItemShow
// @Router /sku_groups/category/{category} [PUT]
func (s *API) UpdateCategoryItemShow(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	uriForm := &CategoryURIForm{}
	if err := c.ShouldBindUri(uriForm); err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	bodyForm := &forms.CategoryItemShow{}
	if err := c.ShouldBindJSON(bodyForm); err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	model := &billing.SKUGroupModel{}
	return model.UpdateCategoryItemShow(uriForm.Category, bodyForm)
}

// @Summary Delete SKU Group Category
// @Schemes
// @Accept json
// @Produce json
// @Param category path string true "category"
// @Success 200 {object} forms.OKType
// @Router /sku_groups/category/{category} [DELETE]
func (s *API) DeleteCategoryItemShow(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	uriForm := &CategoryURIForm{}
	if err := c.ShouldBindUri(uriForm); err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	model := &billing.SKUGroupModel{}
	if err := model.DeleteCategoryItemShow(uriForm.Category); err != nil {
		return nil, err
	}
	return forms.OK, nil
}

func InitializeInnerSKUGroupsRouter(router ginutils.MyRoute) {

	api := &API{}
	router.HandleWithError("POST", "/sku_groups", api.AddSKUGroup)
	router.HandleWithError("GET", "/sku_groups", api.GetSKUGroupList)
	router.HandleWithError("GET", "/sku_groups/category", api.GetCategoryView)
	router.HandleWithError("POST", "/sku_groups/category", api.AddCategoryItemShow)
	router.HandleWithError("GET", "/sku_groups/category/:category", api.GetCategoryItemShow)
	router.HandleWithError("PUT", "/sku_groups/category/:category", api.UpdateCategoryItemShow)
	router.HandleWithError("DELETE", "/sku_groups/category/:category", api.DeleteCategoryItemShow)
	router.HandleWithError("GET", "/sku_groups/:group_id", api.GetSKUGroup)
	router.HandleWithError("PUT", "/sku_groups/:group_id", api.UpdateSKUGroup)
	router.HandleWithError("DELETE", "/sku_groups/:group_id", api.DeleteSKUGroup)

}
func InitializeSKUGroupsRouter(router ginutils.MyRoute) {
	api := &API{}
	router.HandleWithError("POST", "/sku_groups", api.AddSKUGroup)
	router.HandleWithError("GET", "/sku_groups", api.GetSKUGroupList)
	router.HandleWithError("GET", "/sku_groups/category", api.GetCategoryView)
	router.HandleWithError("POST", "/sku_groups/category", api.AddCategoryItemShow)
	router.HandleWithError("GET", "/sku_groups/category/:category", api.GetCategoryItemShow)
	router.HandleWithError("PUT", "/sku_groups/category/:category", api.UpdateCategoryItemShow)
	router.HandleWithError("DELETE", "/sku_groups/category/:category", api.DeleteCategoryItemShow)
	router.HandleWithError("GET", "/sku_groups/:group_id", api.GetSKUGroup)
	router.HandleWithError("PUT", "/sku_groups/:group_id", api.UpdateSKUGroup)
	router.HandleWithError("DELETE", "/sku_groups/:group_id", api.DeleteSKUGroup)
}
