package http

import (
	"log/slog"
	stdhttp "net/http"
	"time"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"

	"qycw/go-server/internal/bootstrap"
	"qycw/go-server/internal/domain/commerce"
	"qycw/go-server/internal/domain/identity"
	"qycw/go-server/internal/jobs"
	qmiddleware "qycw/go-server/internal/middleware"
	"qycw/go-server/internal/plugins"
	"qycw/go-server/internal/response"
)

func NewRouter(app *bootstrap.App, logger *slog.Logger) stdhttp.Handler {
	startedAt := time.Now()
	r := chi.NewRouter()
	r.Use(middleware.RequestID)
	r.Use(middleware.RealIP)
	r.Use(qmiddleware.Recover(logger))
	r.Use(qmiddleware.AccessLog(logger))

	r.Get("/health", func(w stdhttp.ResponseWriter, r *stdhttp.Request) {
		response.OK(w, map[string]any{
			"status":  "ok",
			"version": app.Config.AppVersion,
		})
	})

	identityService := identity.NewService(app.DB, app.Redis, app.Config, logger, app.Plugins)
	taskExecutor := jobs.NewTaskExecutor(app, logger, identityService)
	commerceService := commerce.NewService(app.DB, app.Redis, logger, app.Plugins).WithIdentity(identityService).WithTaskExecutor(taskExecutor)
	auth := qmiddleware.NewAuth(identityService, logger)
	oauthHandler := identity.NewOAuthHandler(identityService, auth, app.Config.FrontendURL, logger)
	requireLicense := qmiddleware.RequireCommercialLicense(app.LicenseEval)
	requirePlugins := qmiddleware.RequireCommercialFeature(app.LicenseEval, "plugins")
	r.Post("/api/host/sync", commerce.NewDownstreamHandler(commerceService, logger).SyncHost)

	r.Route("/api/v1", func(r chi.Router) {
		r.Get("/site-branding", func(w stdhttp.ResponseWriter, r *stdhttp.Request) {
			data, err := commerceService.SiteBranding(r.Context())
			if err != nil {
				response.Detail(w, stdhttp.StatusInternalServerError, err.Error())
				return
			}
			response.OK(w, data)
		})
		r.Get("/site-branding/logo", func(w stdhttp.ResponseWriter, r *stdhttp.Request) {
			path, contentType, err := commerceService.BrandLogoFile(r.Context())
			if err != nil {
				response.Detail(w, stdhttp.StatusNotFound, err.Error())
				return
			}
			w.Header().Set("Content-Type", contentType)
			w.Header().Set("Cache-Control", "public, max-age=3600")
			stdhttp.ServeFile(w, r, path)
		})
		r.Get("/site-branding/assets/{name}", func(w stdhttp.ResponseWriter, r *stdhttp.Request) {
			path, contentType, err := commerceService.BrandAssetFile(chi.URLParam(r, "name"))
			if err != nil {
				response.Detail(w, stdhttp.StatusNotFound, err.Error())
				return
			}
			w.Header().Set("Content-Type", contentType)
			w.Header().Set("Cache-Control", "public, max-age=3600")
			stdhttp.ServeFile(w, r, path)
		})
		r.Get("/health", func(w stdhttp.ResponseWriter, r *stdhttp.Request) {
			response.OK(w, map[string]any{
				"status":  "ok",
				"version": app.Config.AppVersion,
			})
		})

		r.Get("/system/bootstrap", func(w stdhttp.ResponseWriter, r *stdhttp.Request) {
			response.OK(w, map[string]any{
				"app_name":      app.Config.AppName,
				"app_version":   app.Config.AppVersion,
				"db_enabled":    app.DB != nil,
				"redis_enabled": app.Redis != nil,
				"settings_mode": app.Settings.Mode(),
			})
		})

		r.Mount("/store", commerce.NewHandler(commerceService, logger).Routes())
		r.Mount("/activities", commerce.NewHandler(commerceService, logger).ActivityRoutes())
		r.Mount("/auth/oauth", oauthHandler.Routes())

		securityGroups := commerce.NewSecurityGroupHandler(commerceService, auth, logger)
		userOps := commerce.NewUserOpsHandler(commerceService, auth, logger)
		adminCommerce := commerce.NewAdminHandler(commerceService, auth, logger, identityService)
		identityHandler := identity.NewHandler(identityService, logger)

		// 授权管理接口不挂 requireLicense（激活时授权状态还是 missing）
		r.With(auth.RequireRole("admin", "super_admin")).Get("/admin/system-info", func(w stdhttp.ResponseWriter, r *stdhttp.Request) {
			response.OK(w, adminSystemInfo(app, startedAt, r))
		})
		r.With(auth.RequireRole("admin", "super_admin")).Get("/admin/license-status", func(w stdhttp.ResponseWriter, r *stdhttp.Request) {
			response.OK(w, licenseInfo(app, r))
		})
		r.With(auth.RequireRole("admin", "super_admin")).Post("/admin/license/activate", activateLicense(app, logger))
		r.With(requirePlugins).Mount("/admin/plugins", plugins.NewHandler(app.Plugins, auth, logger).Routes())
		r.Mount("/admin/auth", identityHandler.AdminAuthRoutes())
		r.Mount("/", identityHandler.Routes())

		// 以下路由需要商业授权
		r.Group(func(r chi.Router) {
			r.Use(requireLicense)
			r.Mount("/cart", commerce.NewCartHandler(commerceService, auth, logger).Routes())
			r.Mount("/orders", commerce.NewOrderHandler(commerceService, auth, logger).Routes())
			r.Mount("/instances", commerce.NewInstanceHandler(commerceService, auth, logger).Routes())
			r.Mount("/security-groups", securityGroups.Routes())
			r.Mount("/security-group-rules", securityGroups.RuleRoutes())
			r.Mount("/security-group-rule-protocols", securityGroups.ProtocolRoutes())
			r.Mount("/membership", userOps.MembershipRoutes())
			r.Mount("/points", userOps.PointsRoutes())
			r.Mount("/promotion", userOps.PromotionRoutes())
			r.Mount("/agent", userOps.AgentRoutes())
			r.Mount("/notifications", commerce.NewNotificationHandler(commerceService, auth, logger).Routes())
			r.Mount("/recharge", commerce.NewRechargeHandler(commerceService, auth, logger).Routes())
			ticketHandler := commerce.NewTicketHandler(commerceService, auth, logger)
			r.Mount("/tickets", ticketHandler.Routes())
			r.Mount("/admin/tickets", ticketHandler.AdminRoutes())
			r.Get("/vnc/{ticket}", commerce.NewVNCBridgeHandler(commerceService, logger).ServeHTTP)
			r.Mount("/admin/dashboard", adminCommerce.DashboardRoutes())
			r.Mount("/admin/users", adminCommerce.UserRoutes())
			r.Mount("/admin/orders", adminCommerce.OrderRoutes())
			r.Mount("/admin/product-categories", adminCommerce.CategoryRoutes())
			r.Mount("/admin/product-groups", adminCommerce.GroupRoutes())
			r.Mount("/admin/product-catalog", adminCommerce.ProductCatalogRoutes())
			r.Mount("/admin/products", adminCommerce.ProductRoutes())
			r.Mount("/admin/settings", adminCommerce.SettingRoutes())
			r.Mount("/admin/finance", adminCommerce.FinanceRoutes())
			r.Mount("/admin/cloud-servers", adminCommerce.CloudServerRoutes())
			r.Mount("/admin/instances", adminCommerce.InstanceRoutes())
			r.Mount("/admin/announcements", adminCommerce.AnnouncementRoutes())
			r.Mount("/admin/activities", adminCommerce.ActivityRoutes())
			r.Mount("/admin/promo-codes", adminCommerce.PromoCodeRoutes())
			r.Mount("/admin/mall", adminCommerce.MallRoutes())
			r.Mount("/admin/membership", adminCommerce.MembershipRoutes())
			r.Mount("/admin/upstream-actions", adminCommerce.UpstreamActionRoutes())
			r.Mount("/admin/service-orders", adminCommerce.ServiceOrderRoutes())
			r.Mount("/admin", adminCommerce.TaskRoutes())
		})

		r.NotFound(func(w stdhttp.ResponseWriter, r *stdhttp.Request) {
			response.Error(w, stdhttp.StatusNotFound, "Go route not implemented")
		})
	})

	r.NotFound(func(w stdhttp.ResponseWriter, r *stdhttp.Request) {
		response.Error(w, stdhttp.StatusNotFound, "not found")
	})

	return r
}
