package server

import (
	"github.com/casbin/casbin/v2"
	"github.com/gin-gonic/gin"
	apiV1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
	"github.com/go-nunu/nunu-layout-advanced/docs"
	"github.com/go-nunu/nunu-layout-advanced/internal/handler"
	"github.com/go-nunu/nunu-layout-advanced/internal/handler/admin"
	"github.com/go-nunu/nunu-layout-advanced/internal/handler/api/waf"
	"github.com/go-nunu/nunu-layout-advanced/internal/middleware"
	"github.com/go-nunu/nunu-layout-advanced/internal/service"
	"github.com/go-nunu/nunu-layout-advanced/pkg/jwt"
	"github.com/go-nunu/nunu-layout-advanced/pkg/limiter"
	"github.com/go-nunu/nunu-layout-advanced/pkg/log"
	"github.com/go-nunu/nunu-layout-advanced/pkg/server/http"
	"github.com/spf13/viper"
	swaggerfiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
)

func NewHTTPServer(
	logger *log.Logger,
	conf *viper.Viper,
	jwt *jwt.JWT,
	e *casbin.SyncedEnforcer,
	limiterInstance *limiter.Limiter,
	rateLimitMiddleware gin.HandlerFunc,
	userHandler *admin.UserHandler,
	gameShieldHandler *handler.GameShieldHandler,
	gameShieldBackendHandler *handler.GameShieldBackendHandler,
	webForwardingHandler *waf.WebForwardingHandler,
	tcpForwardingHandler *waf.TcpforwardingHandler,
	udpForwardingHandler *waf.UdpForWardingHandler,
	globalLimitHandler *waf.GlobalLimitHandler,
	adminHandler *admin.AdminHandler,
	gatewayIpAdminHandler *admin.GatewayIpAdminHandler,
	allowAnddenyHandler *waf.AllowAndDenyIpHandler,
	ccHandler *waf.CcHandler,
	logService service.LogService,
	ccIpListHandler *waf.CcIpListHandler,
	cdnLogHandler *waf.CdnLogHandler,
	logHandler *admin.LogHandler,
	wafLogHandler *admin.WafLogHandler,
) *http.Server {
	gin.SetMode(gin.DebugMode)
	s := http.NewServer(
		gin.Default(),
		logger,
		http.WithServerHost(conf.GetString("http.host")),
		http.WithServerPort(conf.GetInt("http.port")),
	)

	// swagger doc
	docs.SwaggerInfo.BasePath = "/v1"
	s.GET("/swagger/*any", ginSwagger.WrapHandler(
		swaggerfiles.Handler,
		//ginSwagger.URL(fmt.Sprintf("http://localhost:%d/swagger/doc.json", conf.GetInt("app.http.port"))),
		ginSwagger.DefaultModelsExpandDepth(-1),
		ginSwagger.PersistAuthorization(true),
	))

	s.Use(
		middleware.CORSMiddleware(),
		middleware.ResponseLogMiddleware(logger),
		middleware.RequestLogMiddleware(logger),
		middleware.OperationLogMiddleware(logService),
		//middleware.SignMiddleware(log),
		rateLimitMiddleware,
	)
	s.GET("/", func(ctx *gin.Context) {
		logger.WithContext(ctx).Info("hello")
		apiV1.HandleSuccess(ctx, map[string]interface{}{
			":)": "Thank you for using nunu!",
		})
	})

	v1 := s.Group("/v1")
	{
		// No route group has permission
		noAuthRouter := v1.Group("/")
		{
			// 使用增强的Limiter.GetAPIConfig方法获取特定API的限流配置

			// 登录API限流
			loginConfig := limiterInstance.GetAPIConfig("login")
			noAuthRouter.POST("/login", middleware.IPRateLimitMiddleware(loginConfig), adminHandler.Login)

			//// 注册API限流
			//registerConfig := limiterInstance.GetAPIConfig("register")
			//noAuthRouter.POST("/register", middleware.IPRateLimitMiddleware(registerConfig), userHandler.Register)

			// 创建IP白名单实例
			ipAllowlist := middleware.NewIPAllowlist(conf, logger)
			ipAllowlistMiddleware := ipAllowlist.IPAllowlistMiddleware()

			// 为GameShield相关接口添加IP白名单保护
			noAuthRouter.POST("/gameShield/add", ipAllowlistMiddleware, gameShieldHandler.SubmitGameShield)
			noAuthRouter.POST("/gameShield/getField", ipAllowlistMiddleware, gameShieldHandler.GetGameShieldField)
			noAuthRouter.POST("/gameShield/getKey", ipAllowlistMiddleware, gameShieldHandler.GetGameShieldKey)
			noAuthRouter.POST("/gameShield/edit", ipAllowlistMiddleware, gameShieldHandler.EditGameShield)
			noAuthRouter.POST("/gameShield/delete", ipAllowlistMiddleware, gameShieldHandler.DeleteGameShield)
			noAuthRouter.POST("/gameShield/getOnline", ipAllowlistMiddleware, gameShieldHandler.GetGameShieldOnlineList)
			noAuthRouter.POST("/gameShield/IsExistKey", gameShieldHandler.IsExistGameShieldKey)
			noAuthRouter.POST("/webForward/get", ipAllowlistMiddleware, webForwardingHandler.GetWebForwarding)
			noAuthRouter.POST("/webForward/getList", ipAllowlistMiddleware, webForwardingHandler.GetWebForwardingList)
			noAuthRouter.POST("/webForward/add", ipAllowlistMiddleware, webForwardingHandler.AddWebForwarding)
			noAuthRouter.POST("/webForward/edit", ipAllowlistMiddleware, webForwardingHandler.EditWebForwarding)
			noAuthRouter.POST("/webForward/delete", ipAllowlistMiddleware, webForwardingHandler.DeleteWebForwarding)

			noAuthRouter.POST("/tcpForward/add", ipAllowlistMiddleware, tcpForwardingHandler.AddTcpForwarding)
			noAuthRouter.POST("/tcpForward/get", ipAllowlistMiddleware, tcpForwardingHandler.GetTcpforwarding)
			noAuthRouter.POST("/tcpForward/getList", ipAllowlistMiddleware, tcpForwardingHandler.GetTcpForwardingList)
			noAuthRouter.POST("/tcpForward/edit", ipAllowlistMiddleware, tcpForwardingHandler.EditTcpForwarding)
			noAuthRouter.POST("/tcpForward/delete", ipAllowlistMiddleware, tcpForwardingHandler.DeleteTcpForwarding)
			noAuthRouter.POST("/udpForward/get", ipAllowlistMiddleware, udpForwardingHandler.GetUdpForWarding)
			noAuthRouter.POST("/udpForward/getList", ipAllowlistMiddleware, udpForwardingHandler.GetUdpForWardingList)
			noAuthRouter.POST("/udpForward/add", ipAllowlistMiddleware, udpForwardingHandler.AddUdpForWarding)
			noAuthRouter.POST("/udpForward/edit", ipAllowlistMiddleware, udpForwardingHandler.EditUdpForWarding)
			noAuthRouter.POST("/udpForward/delete", ipAllowlistMiddleware, udpForwardingHandler.DeleteUdpForWarding)

			noAuthRouter.POST("/gameShieldBackend/add", ipAllowlistMiddleware, gameShieldBackendHandler.AddGameShieldBackend)
			noAuthRouter.POST("/gameShieldBackend/edit", ipAllowlistMiddleware, gameShieldBackendHandler.EditGameShieldBackend)
			noAuthRouter.POST("/gameShieldBackend/delete", ipAllowlistMiddleware, gameShieldBackendHandler.DeleteGameShieldBackend)
			noAuthRouter.POST("/gameShieldBackend/replacementSourceMachineIp", ipAllowlistMiddleware, gameShieldBackendHandler.ReplacementSourceMachineIp)
			noAuthRouter.POST("/globalLimit/add", ipAllowlistMiddleware, globalLimitHandler.AddGlobalLimit)
			noAuthRouter.POST("/globalLimit/edit", ipAllowlistMiddleware, globalLimitHandler.EditGlobalLimit)
			noAuthRouter.POST("/globalLimit/delete", ipAllowlistMiddleware, globalLimitHandler.DeleteGlobalLimit)

			noAuthRouter.POST("/allowAndDeny/get", ipAllowlistMiddleware, allowAnddenyHandler.GetAllowAndDenyIp)
			noAuthRouter.POST("/allowAndDeny/getList", ipAllowlistMiddleware, allowAnddenyHandler.GetAllowAndDenyIpList)
			noAuthRouter.POST("/allowAndDeny/add", ipAllowlistMiddleware, allowAnddenyHandler.AddAllowAndDenyIp)
			noAuthRouter.POST("/allowAndDeny/edit", ipAllowlistMiddleware, allowAnddenyHandler.EditAllowAndDenyIp)
			noAuthRouter.POST("/allowAndDeny/delete", ipAllowlistMiddleware, allowAnddenyHandler.DeleteAllowAndDenyIp)

			noAuthRouter.POST("/cc/getList", ipAllowlistMiddleware, ccHandler.GetCcList)
			noAuthRouter.POST("/cc/editState", ipAllowlistMiddleware, ccHandler.EditCcState)
			noAuthRouter.POST("/cc/addWhiteOneClick", ipAllowlistMiddleware, ccHandler.AddWhiteOneClick)

			noAuthRouter.POST("/ccIpList/getList", ipAllowlistMiddleware, ccIpListHandler.GetCcIpList)
			noAuthRouter.POST("/ccIpList/add", ipAllowlistMiddleware, ccIpListHandler.AddCcIpList)
			noAuthRouter.POST("/ccIpList/edit", ipAllowlistMiddleware, ccIpListHandler.EditCcIpList)
			noAuthRouter.POST("/ccIpList/delete", ipAllowlistMiddleware, ccIpListHandler.DelCcIpList)

			noAuthRouter.POST("/cdnLog/getList", ipAllowlistMiddleware, cdnLogHandler.GetCdnLog)

		}
		// Non-strict permission routing group
		//noStrictAuthRouter := v1.Group("/").Use(middleware.NoStrictAuth(jwt, logger))
		//{
		//	noStrictAuthRouter.GET("/user", userHandler.GetProfile)
		//}

		// Strict permission routing group
		strictAuthRouter := v1.Group("/").Use(middleware.StrictAuth(jwt, logger), middleware.AuthMiddleware(e))
		{
			strictAuthRouter.GET("/user", userHandler.GetUsers)

			strictAuthRouter.GET("/menus", adminHandler.GetMenus)
			strictAuthRouter.GET("/admin/menus", adminHandler.GetAdminMenus)
			strictAuthRouter.POST("/admin/menu", adminHandler.MenuCreate)
			strictAuthRouter.PUT("/admin/menu", adminHandler.MenuUpdate)
			strictAuthRouter.DELETE("/admin/menu", adminHandler.MenuDelete)

			strictAuthRouter.GET("/admin/users", adminHandler.GetAdminUsers)
			strictAuthRouter.GET("/admin/user", adminHandler.GetAdminUser)
			strictAuthRouter.PUT("/admin/user", adminHandler.AdminUserUpdate)
			strictAuthRouter.POST("/admin/user", adminHandler.AdminUserCreate)
			strictAuthRouter.DELETE("/admin/user", adminHandler.AdminUserDelete)
			strictAuthRouter.GET("/admin/user/permissions", adminHandler.GetUserPermissions)
			strictAuthRouter.GET("/admin/role/permissions", adminHandler.GetRolePermissions)
			strictAuthRouter.PUT("/admin/role/permission", adminHandler.UpdateRolePermission)
			strictAuthRouter.GET("/admin/roles", adminHandler.GetRoles)
			strictAuthRouter.POST("/admin/role", adminHandler.RoleCreate)
			strictAuthRouter.PUT("/admin/role", adminHandler.RoleUpdate)
			strictAuthRouter.DELETE("/admin/role", adminHandler.RoleDelete)

			strictAuthRouter.GET("/admin/apis", adminHandler.GetApis)
			strictAuthRouter.POST("/admin/api", adminHandler.ApiCreate)
			strictAuthRouter.PUT("/admin/api", adminHandler.ApiUpdate)
			strictAuthRouter.DELETE("/admin/api", adminHandler.ApiDelete)


			strictAuthRouter.GET("/gatewayIp/get", gatewayIpAdminHandler.GetGatewayIpAdmin)
			strictAuthRouter.GET("/gatewayIp/getList", gatewayIpAdminHandler.GetGatewayIpAdminList)
			strictAuthRouter.POST("/gatewayIp/add", gatewayIpAdminHandler.AddGatewayIpAdmin)
			strictAuthRouter.PUT("/gatewayIp/edit", gatewayIpAdminHandler.EditGatewayIpAdmin)
			strictAuthRouter.DELETE("/gatewayIp/del", gatewayIpAdminHandler.DeleteGatewayIpAdmin)
			strictAuthRouter.DELETE("/gatewayIp/delList", gatewayIpAdminHandler.DeleteGatewayIpsAdmin)


			strictAuthRouter.GET("/log/get", logHandler.GetLog)
			strictAuthRouter.GET("/log/getList", logHandler.GetLogList)

			strictAuthRouter.GET("admin/wafLog/get", wafLogHandler.GetWafLog)
			strictAuthRouter.GET("admin/wafLog/getList", wafLogHandler.GetWafLogList)
			strictAuthRouter.POST("admin/wafLog/export", wafLogHandler.ExportWafLog)
			strictAuthRouter.GET("admin/wafLog/getApiDescriptions", wafLogHandler.GetApiDescriptions)
		}
	}

	//api := s.Group("/api")
	//{
	//	apiAuthRouter := api.Group("/").Use(middleware.StrictAuth(jwt, logger), middleware.AuthMiddleware(e))
	//	{
	//		apiAuthRouter.GET("/gatewayIp/get", gatewayIpAdminHandler.GetGatewayIpAdmin)
	//		apiAuthRouter.GET("/gatewayIp/getList", gatewayIpAdminHandler.GetGatewayIpAdminList)
	//		apiAuthRouter.POST("/gatewayIp/add", gatewayIpAdminHandler.AddGatewayIpAdmin)
	//		apiAuthRouter.PUT("/gatewayIp/edit", gatewayIpAdminHandler.EditGatewayIpAdmin)
	//	}
	//
	//
	//}

	return s
}
