package router

import (
	"net/http"

	"github.com/0xJacky/Nginx-UI/api/analytic"
	"github.com/0xJacky/Nginx-UI/api/audit"
	"github.com/0xJacky/Nginx-UI/api/backup"
	"github.com/0xJacky/Nginx-UI/api/certificate"
	"github.com/0xJacky/Nginx-UI/api/cluster"
	"github.com/0xJacky/Nginx-UI/api/config"
	"github.com/0xJacky/Nginx-UI/api/crypto"
	"github.com/0xJacky/Nginx-UI/api/event"
	"github.com/0xJacky/Nginx-UI/api/external_notify"
	"github.com/0xJacky/Nginx-UI/api/geolite"
	"github.com/0xJacky/Nginx-UI/api/license"
	"github.com/0xJacky/Nginx-UI/api/llm"
	"github.com/0xJacky/Nginx-UI/api/nginx"
	nginxLog "github.com/0xJacky/Nginx-UI/api/nginx_log"
	"github.com/0xJacky/Nginx-UI/api/notification"
	"github.com/0xJacky/Nginx-UI/api/pages"
	"github.com/0xJacky/Nginx-UI/api/public"
	"github.com/0xJacky/Nginx-UI/api/settings"
	"github.com/0xJacky/Nginx-UI/api/sites"
	"github.com/0xJacky/Nginx-UI/api/streams"
	"github.com/0xJacky/Nginx-UI/api/system"
	"github.com/0xJacky/Nginx-UI/api/template"
	"github.com/0xJacky/Nginx-UI/api/terminal"
	"github.com/0xJacky/Nginx-UI/api/upstream"
	"github.com/0xJacky/Nginx-UI/api/user"
	"github.com/0xJacky/Nginx-UI/internal/middleware"
	"github.com/0xJacky/Nginx-UI/mcp"
	"github.com/gin-gonic/gin"
	"github.com/uozi-tech/cosy"
	"github.com/uozi-tech/cosy/debug"
)

func InitRouter() {
	r := cosy.GetEngine()

	r.Use(audit.LoggingMiddleware())

	r.SetTrustedProxies(nil)

	// Add CORS middleware to allow all origins
	r.Use(middleware.CORS())

	initEmbedRoute(r)

	pages.InitRouter(r)

	r.NoRoute(func(c *gin.Context) {
		c.JSON(http.StatusNotFound, gin.H{
			"message": "not found",
		})
	})

	mcp.InitRouter(r)

	root := r.Group("/api", middleware.IPWhiteList())
	{
		public.InitRouter(root)
		crypto.InitPublicRouter(root)
		user.InitAuthRouter(root)
		license.InitRouter(root)

		system.InitPublicRouter(root)
		system.InitSelfCheckRouter(root)
		backup.InitRouter(root)

		// Local-only routes (no proxy) - authorization required
		local := root.Group("/", middleware.AuthRequired())
		{
			llm.InitLocalRouter(local)
		}

		// Authorization required and not websocket request
		g := root.Group("/", middleware.AuthRequired(), middleware.Proxy())
		{
			debug.InitRouter(g)
			user.InitUserRouter(g)
			analytic.InitRouter(g)
			user.InitManageUserRouter(g)
			nginx.InitRouter(g)
			sites.InitRouter(g)
			streams.InitRouter(g)
			config.InitRouter(g)
			template.InitRouter(g)
			certificate.InitCertificateRouter(g)
			certificate.InitDNSCredentialRouter(g)
			certificate.InitAcmeUserRouter(g)
			system.InitPrivateRouter(g)
			settings.InitRouter(g)
			llm.InitRouter(g)
			cluster.InitRouter(g)
			notification.InitRouter(g)
			external_notify.InitRouter(g)
			backup.InitAutoBackupRouter(g)
			nginxLog.InitRouter(g)
			g.GET("/geolite/status", geolite.GetStatus)
		}

		// Authorization required and websocket request
		w := root.Group("/", middleware.AuthRequired(), middleware.ProxyWs())
		{
			analytic.InitWebSocketRouter(w)
			certificate.InitCertificateWebSocketRouter(w)
			event.InitRouter(w)
			o := w.Group("", middleware.RequireSecureSession())
			{
				terminal.InitRouter(o)
			}
			nginxLog.InitWebSocketRouter(w)
			upstream.InitRouter(w)
			system.InitWebSocketRouter(w)
			nginx.InitWebSocketRouter(w)
			cluster.InitWebSocketRouter(w)
			w.GET("/geolite/download", geolite.DownloadGeoLiteDB)
		}
	}
}
