package apiserver

import (
	"fmt"
	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/test"

	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"

	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/alert"
	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/cron"

	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/cube"
	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/provider"

	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/budget"
	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/resource"

	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/billing"
	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/department"
	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/search"
	"github.com/pingcap-inc/pchub/internal/pkg/code"
	"github.com/pingcap-inc/pchub/pkg/errors"
	"github.com/pingcap-inc/pchub/pkg/util/ginres"

	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/approval"
	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/lark"
	memberRole "github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/member_role"
	starResource "github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/star_resource"
	"github.com/pingcap-inc/pchub/internal/apiserver/controller/v1/user"
	"github.com/pingcap-inc/pchub/internal/apiserver/store/mysql"
	"github.com/pingcap-inc/pchub/internal/pkg/middleware"
)

func initRouter(g *gin.Engine) {
	installController(g)
}

func installController(g *gin.Engine) *gin.Engine {
	g.NoRoute(func(c *gin.Context) {
		ginres.WriteResponse(c, errors.WithCode(code.ErrNotFound, "Not found."), nil)
	})

	storeIns, _ := mysql.GetMySQLFactoryOr(nil)

	v1 := g.Group("/v1")
	{
		publicv1 := v1.Group("")

		larkEventController := lark.NewLarkEventController(storeIns)
		go larkEventController.InitAskPCHUserList()

		publicv1.POST("/lark/event", larkEventController.HandleEvent)
		publicv1.POST("/lark/event-mock", larkEventController.HandleMockEvent)

		larkApprOptionsController := lark.NewLarkApprOptionsController(storeIns)
		publicv1.POST("/lark/approvals/soptions/:entity", larkApprOptionsController.Get)

		cronController := cron.NewCronController(storeIns)
		publicv1.POST("/cron/:function", cronController.StartSync)

		// 测试控制器 - 阿里云权限同步测试
		testController := test.NewTestController(storeIns)
		publicv1.POST("/test/alicloud/sync", testController.TestAlicloudSync)

		authv1 := v1.Group("", middleware.Auth())

		cubeController := cube.NewCubeController(storeIns)
		authv1.POST("/cube/token", cubeController.GetToken)

		memberRoleController := memberRole.NewMemberRoleController(storeIns)
		authv1.GET("/member-roles", memberRoleController.Get)

		providerController := provider.NewProviderController(storeIns)
		authv1.GET("/providers", providerController.List)

		budgetController := budget.NewBudgetController(storeIns)
		authv1.GET("/budgets/latestfy", budgetController.ListLatestFY)
		authv1.POST("/budgets/set", budgetController.SetBudget)

		userController := user.NewUserController(storeIns)
		authv1.GET("/user-info", userController.Get)
		authv1.GET("/users/search", userController.Search)
		authv1.POST("/feedback-group", userController.JoinFeedbackGroup)

		searchController := search.NewSearchController(storeIns)
		authv1.GET("/receivers/search", searchController.SearchReceivers)

		departmentController := department.NewDepartmentController(storeIns)
		authv1.POST("/departments/sync", departmentController.Sync)
		authv1.GET("/departments", departmentController.List)

		resourceController := resource.NewResourceController(storeIns)
		authv1.GET("/resource/detail", resourceController.Detail)
		authv1.GET("/resource/name-check", resourceController.NameCheck)
		authv1.PATCH("/resource", resourceController.UpdateInfo)
		authv1.GET("/resource/search", resourceController.Search)
		authv1.PATCH("/resource/transfer", resourceController.Transfer)

		billingController := billing.NewBillingController(storeIns)
		authv1.GET("/billings", billingController.List)
		authv1.POST("/billings/check-alerts", billingController.CheckCostAlerts)

		approvalController := approval.NewApprovalController(storeIns)
		authv1.GET("/approval", approvalController.GetAllApproval)
		authv1.POST("/approval", approvalController.CreateApproval)
		authv1.POST("/approval/subscribe", approvalController.Subscribe)
		authv1.GET("/approval/instance/:instanceCode", approvalController.GetApprovalByInstanceCode)

		alertController := alert.NewAlertController(storeIns)
		authv1.POST("/alert", alertController.CreateAlert)
		authv1.PATCH("/alert", alertController.UpdateAlert)
		authv1.GET("/alerts", alertController.ListAlerts)
		authv1.DELETE("/alert", alertController.DeleteAlert)
		authv1.POST("/alert/confirm", alertController.ConfirmAlert)

		starResController := starResource.NewStarResourceController(storeIns)
		authv1.GET("/star-resources", starResController.List)
		authv1.POST("/star-resource", starResController.ToggleStarResource)

		fmt.Println("test file::" + viper.GetString("gcp.service_account_file"))
	}

	return g
}
