package tests

import (
	"encoding/json"
	"net/http"
	"testing"

	"github.com/pingcap/dbaas/billing2/db/entity"
	"github.com/pingcap/dbaas/billing2/utils/ginutils"
	"github.com/pingcap/dbaas/billing2/utils/tests"
	"github.com/pingcap/dbaas/billing2/utils/tests/datainit"
	"github.com/stretchr/testify/suite"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/dbaas/billing2/api"
)

type SetTenantMonthlyCacheTestSuite struct {
	tests.BillingTestSuite
	router *gin.Engine
}

func (suite *SetTenantMonthlyCacheTestSuite) SetupTest() {
	suite.BillingTestSuite.SetupTest()
	suite.router = gin.New()
	suite.router.Use(ginutils.ErrorMiddleWare)
	api.InitializeCostExplorerRouter(ginutils.MyRoute{Route: suite.router})
}

func TestSetTenantMonthlyCacheTestSuite(t *testing.T) {
	suite.Run(t, new(SetTenantMonthlyCacheTestSuite))
}

func (suite *SetTenantMonthlyCacheTestSuite) TestSetTenantMonthlyCacheSuccess() {
	assert := suite.Assert()
	datainit.CreateBillingConfig(1, entity.BillingConfigType_DirectCustomer)
	_, err := datainit.CreateInvoice(uint(1))
	assert.NoError(err)

	req := map[string]interface{}{
		"tenant_id": 1,
		"month":     "2021-11",
	}
	w := tests.PerformRequest(suite.router, "POST", "/setTenantMonthlyCache", req)
	assert.Equal(http.StatusOK, w.Code)

	var resp map[string]interface{}
	assert.NoError(json.Unmarshal(w.Body.Bytes(), &resp))
	assert.Equal("Monthly cost cache set successfully", resp["message"])
}

func (suite *SetTenantMonthlyCacheTestSuite) TestSetTenantMonthlyCacheInvalidMonth() {
	assert := suite.Assert()

	req := map[string]interface{}{
		"tenant_id": 1,
		"month":     "invalid-month",
	}
	w := tests.PerformRequest(suite.router, "POST", "/setTenantMonthlyCache", req)
	assert.Equal(http.StatusBadRequest, w.Code)

	var resp map[string]interface{}
	assert.NoError(json.Unmarshal(w.Body.Bytes(), &resp))
	assert.Equal("Invalid month format, should be YYYY-MM", resp["error"])
}

func (suite *SetTenantMonthlyCacheTestSuite) TestSetTenantMonthlyCacheMissingFields() {
	assert := suite.Assert()

	// Missing month
	req := map[string]interface{}{
		"tenant_id": 1,
	}
	w := tests.PerformRequest(suite.router, "POST", "/setTenantMonthlyCache", req)
	assert.Equal(http.StatusBadRequest, w.Code)

	// Missing tenant_id
	req = map[string]interface{}{
		"month": "2021-11",
	}
	w = tests.PerformRequest(suite.router, "POST", "/setTenantMonthlyCache", req)
	assert.Equal(http.StatusBadRequest, w.Code)
}
