package router

import (
	"bindbox-game/configs"
	"bindbox-game/internal/alert"
	activityapi "bindbox-game/internal/api/activity"
	"bindbox-game/internal/api/admin"
	appapi "bindbox-game/internal/api/app"
	commonapi "bindbox-game/internal/api/common"
	gameapi "bindbox-game/internal/api/game"
	payapi "bindbox-game/internal/api/pay"
	taskcenterapi "bindbox-game/internal/api/task_center"
	userapi "bindbox-game/internal/api/user"
	"bindbox-game/internal/dblogger"
	"bindbox-game/internal/pkg/core"
	"bindbox-game/internal/pkg/logger"
	"bindbox-game/internal/pkg/redis"
	"bindbox-game/internal/repository/mysql"
	"bindbox-game/internal/router/interceptor"
	activitysvc "bindbox-game/internal/service/activity"
	tasksvc "bindbox-game/internal/service/task_center"
	titlesvc "bindbox-game/internal/service/title"
	usersvc "bindbox-game/internal/service/user"
	"context"

	"github.com/pkg/errors"
)

func NewHTTPMux(logger logger.CustomLogger, db mysql.Repo) (core.Mux, func(), error) {
	if logger == nil {
		return nil, nil, errors.New("logger required")
	}

	if db == nil {
		return nil, nil, errors.New("db required")
	}

	mux, err := core.New(logger,
		core.WithEnableCors(),
		core.WithEnableSwagger(),
		core.WithEnablePProf(),
		core.WithAlertNotify(alert.NotifyHandler()),
		core.WithRequestLogger(dblogger.LoggerHandler(db)),
	)

	if err != nil {
		panic(err)
	}

	// Redis is initialized in main.go
	rdb := redis.GetClient()

	// Instantiate Services
	userSvc := usersvc.New(logger, db)
	titleSvc := titlesvc.New(logger, db)
	taskSvc := tasksvc.New(logger, db, rdb, userSvc, titleSvc)
	activitySvc := activitysvc.New(logger, db, userSvc, rdb)

	// Context for Worker
	ctx, cancel := context.WithCancel(context.Background())
	// Start task center worker
	go taskSvc.StartWorker(ctx)

	// 实例化拦截器
	adminHandler := admin.New(logger, db, rdb)
	activityHandler := activityapi.New(logger, db, rdb, taskSvc)
	taskCenterHandler := taskcenterapi.New(logger, db, taskSvc)

	// app端的API
	userHandler := userapi.New(logger, db, taskSvc)
	// TODO: Check if userHandler and userAppHandler are redundant or distinct.
	// Based on typical project structure, `internal/api/user` is likely `userapp`.
	// `internal/api/admin/users_admin.go` might be `userapi` (admin).
	// Let's correct the `appapi` typo first.
	commonHandler := commonapi.New(logger, db)
	payHandler := payapi.New(logger, db, taskSvc, activitySvc)
	gameHandler := gameapi.New(logger, db, rdb, userSvc)
	intc := interceptor.New(logger, db)

	// 内部服务接口路由组 (供 Nakama 调用)
	// 使用 X-Internal-Key 头进行验证，防止外部访问
	internalRouter := mux.Group("/api/internal", func(ctx core.Context) {
		internalKey := ctx.GetHeader("X-Internal-Key")
		// 从配置文件读取内部 API 密钥
		expectedKey := configs.Get().Internal.ApiKey
		if expectedKey == "" {
			expectedKey = "bindbox-internal-secret-2024" // 默认值（仅用于向后兼容）
		}
		if internalKey != expectedKey {
			ctx.AbortWithError(core.Error(403, 10403, "Forbidden: Invalid internal key"))
			return
		}
	})
	{
		internalRouter.POST("/game/verify", gameHandler.VerifyTicket())
		internalRouter.POST("/game/validate-token", gameHandler.ValidateGameToken())
		internalRouter.POST("/game/settle", gameHandler.SettleGame())
		internalRouter.POST("/game/consume-ticket", gameHandler.ConsumeTicket())
		internalRouter.GET("/game/minesweeper/config", gameHandler.GetMinesweeperConfig())
	}

	// 管理端非认证接口路由组
	adminNonAuthApiRouter := mux.Group("/api/admin")
	{
		adminNonAuthApiRouter.POST("/login", adminHandler.Login())
	}

	// 管理端认证接口路由组
	adminAuthApiRouter := mux.Group("/api/admin", core.WrapAuthHandler(intc.AdminTokenAuthVerify), intc.RequireAdminRole())

	// 系统管理接口（为前端模板路径兼容，挂载到 /api）
	systemApiRouter := mux.Group("/api", core.WrapAuthHandler(intc.AdminTokenAuthVerify), intc.RequireAdminRole())
	{
		// 管理员账号维护接口移除（未被前端使用）

		adminAuthApiRouter.GET("/activity_categories", adminHandler.ListActivityCategories())

		// 任务中心管理端
		adminAuthApiRouter.GET("/task-center/tasks", taskCenterHandler.ListTasksForAdmin())
		adminAuthApiRouter.POST("/task-center/tasks", taskCenterHandler.CreateTaskForAdmin())
		adminAuthApiRouter.PUT("/task-center/tasks/:id", taskCenterHandler.ModifyTaskForAdmin())
		adminAuthApiRouter.DELETE("/task-center/tasks/:id", taskCenterHandler.DeleteTaskForAdmin())
		adminAuthApiRouter.POST("/task-center/tasks/:id/tiers", taskCenterHandler.UpsertTaskTiersForAdmin())
		adminAuthApiRouter.GET("/task-center/tasks/:id/tiers", taskCenterHandler.ListTaskTiersForAdmin())
		adminAuthApiRouter.POST("/task-center/tasks/:id/rewards", taskCenterHandler.UpsertTaskRewardsForAdmin())
		adminAuthApiRouter.GET("/task-center/tasks/:id/rewards", taskCenterHandler.ListTaskRewardsForAdmin())
		adminAuthApiRouter.POST("/task-center/events/order-paid", taskCenterHandler.SimulateOrderPaid())
		adminAuthApiRouter.POST("/task-center/events/invite-success", taskCenterHandler.SimulateInviteSuccess())

		// 工作台
		adminAuthApiRouter.GET("/dashboard/cards", adminHandler.DashboardCards())
		adminAuthApiRouter.GET("/dashboard/user_trend", adminHandler.DashboardUserTrend())
		adminAuthApiRouter.GET("/dashboard/draw_trend", adminHandler.DashboardDrawTrend())
		adminAuthApiRouter.GET("/dashboard/sales_draw_trend", adminHandler.DashboardSalesDrawTrend())
		adminAuthApiRouter.GET("/dashboard/retention_analytics", adminHandler.DashboardRetentionAnalytics())
		adminAuthApiRouter.GET("/dashboard/new_users", adminHandler.DashboardNewUsers())
		adminAuthApiRouter.GET("/dashboard/draw_stream", adminHandler.DashboardDrawStream())
		adminAuthApiRouter.GET("/dashboard/todos", adminHandler.DashboardTodos())
		adminAuthApiRouter.GET("/dashboard/order_funnel", adminHandler.DashboardOrderFunnel())
		adminAuthApiRouter.GET("/dashboard/activities", adminHandler.DashboardActivities())
		adminAuthApiRouter.GET("/dashboard/activity_prize_analysis", adminHandler.DashboardActivityPrizeAnalysis())
		adminAuthApiRouter.GET("/dashboard/user_overview", adminHandler.DashboardUserOverview())

		// 运营分析
		adminAuthApiRouter.GET("/operations/user_economics", adminHandler.DashboardUserEconomics())
		adminAuthApiRouter.GET("/operations/prize_distribution", adminHandler.DashboardPrizeDistribution())
		adminAuthApiRouter.GET("/dashboard/product_performance", adminHandler.OperationsProductPerformance())
		adminAuthApiRouter.GET("/dashboard/coupon_effectiveness", adminHandler.OperationsCouponEffectiveness())
		adminAuthApiRouter.GET("/dashboard/points_economy_summary", adminHandler.OperationsPointsEconomySummary())
		adminAuthApiRouter.GET("/dashboard/points_trend", adminHandler.OperationsPointsTrend())
		adminAuthApiRouter.GET("/dashboard/points_structure", adminHandler.OperationsPointsStructure())
		adminAuthApiRouter.GET("/dashboard/inventory_alerts", adminHandler.OperationsInventoryAlerts())
		adminAuthApiRouter.GET("/dashboard/risk_events", adminHandler.OperationsRiskEvents())
		adminAuthApiRouter.GET("/dashboard/live_winners", adminHandler.DashboardLiveWinners())
		adminAuthApiRouter.GET("/dashboard/order_trend", adminHandler.DashboardOrderTrend())
		adminAuthApiRouter.GET("/dashboard/activity_stats", adminHandler.DashboardActivityStats())
		adminAuthApiRouter.GET("/dashboard/item_card_sales", adminHandler.DashboardItemCardSales())
		adminAuthApiRouter.POST("/activities", intc.RequireAdminAction("activity:create"), adminHandler.CreateActivity())
		adminAuthApiRouter.GET("/activities", intc.RequireAdminAction("activity:view"), adminHandler.ListActivities())
		adminAuthApiRouter.PUT("/activities/:activity_id", intc.RequireAdminAction("activity:modify"), adminHandler.ModifyActivity())
		adminAuthApiRouter.DELETE("/activities/:activity_id", intc.RequireAdminAction("activity:delete"), adminHandler.DeleteActivity())
		adminAuthApiRouter.GET("/activities/:activity_id", intc.RequireAdminAction("activity:view"), adminHandler.GetActivityDetail())
		adminAuthApiRouter.POST("/lottery/activities/:activity_id/scheduled_config", intc.RequireAdminAction("activity:modify"), adminHandler.SetScheduledConfig())
		adminAuthApiRouter.GET("/lottery/activities/:activity_id/scheduled_config", intc.RequireAdminAction("activity:view"), adminHandler.GetScheduledConfig())
		adminAuthApiRouter.POST("/activities/:activity_id/copy", intc.RequireAdminAction("activity:create"), adminHandler.CopyActivity())
		adminAuthApiRouter.GET("/activities/:activity_id/issues", intc.RequireAdminAction("activity:view"), adminHandler.ListActivityIssues())
		adminAuthApiRouter.POST("/activities/:activity_id/issues", intc.RequireAdminAction("activity:modify"), adminHandler.CreateActivityIssue())
		adminAuthApiRouter.PUT("/activities/:activity_id/issues/:issue_id", intc.RequireAdminAction("activity:modify"), adminHandler.ModifyActivityIssue())
		adminAuthApiRouter.DELETE("/activities/:activity_id/issues/:issue_id", intc.RequireAdminAction("activity:delete"), adminHandler.DeleteActivityIssue())
		adminAuthApiRouter.POST("/activities/:activity_id/issues/:issue_id/rewards", intc.RequireAdminAction("activity:modify"), adminHandler.CreateIssueRewards())
		adminAuthApiRouter.GET("/activities/:activity_id/issues/:issue_id/rewards", intc.RequireAdminAction("activity:view"), adminHandler.ListIssueRewards())
		adminAuthApiRouter.PUT("/activities/:activity_id/issues/:issue_id/rewards/:reward_id", intc.RequireAdminAction("activity:modify"), adminHandler.ModifyIssueReward())
		adminAuthApiRouter.PUT("/activities/:activity_id/issues/:issue_id/rewards/batch", intc.RequireAdminAction("activity:modify"), adminHandler.BatchModifyIssueRewards())
		adminAuthApiRouter.DELETE("/activities/:activity_id/issues/:issue_id/rewards/:reward_id", intc.RequireAdminAction("activity:delete"), adminHandler.DeleteIssueReward())

		// 已移除：批量造数/批量删除用户接口（未被前端使用）

		// 商品管理：分类与商品
		adminAuthApiRouter.POST("/product_categories", adminHandler.CreateProductCategory())
		adminAuthApiRouter.PUT("/product_categories/:category_id", adminHandler.ModifyProductCategory())
		adminAuthApiRouter.DELETE("/product_categories/:category_id", adminHandler.DeleteProductCategory())
		adminAuthApiRouter.GET("/product_categories", adminHandler.ListProductCategories())
		adminAuthApiRouter.POST("/products", intc.RequireAdminAction("product:create"), adminHandler.CreateProduct())
		adminAuthApiRouter.PUT("/products/:product_id", intc.RequireAdminAction("product:modify"), adminHandler.ModifyProduct())
		adminAuthApiRouter.PUT("/products/batch", intc.RequireAdminAction("product:batch:modify"), adminHandler.BatchUpdateProducts())
		adminAuthApiRouter.DELETE("/products/:product_id", intc.RequireAdminAction("product:delete"), adminHandler.DeleteProduct())
		adminAuthApiRouter.GET("/products", intc.RequireAdminAction("product:view"), adminHandler.ListProducts())
		adminAuthApiRouter.POST("/auth/refresh", adminHandler.RefreshToken())

		// 轮播图管理
		adminAuthApiRouter.POST("/banners", intc.RequireAdminAction("banner:create"), adminHandler.CreateBanner())
		adminAuthApiRouter.PUT("/banners/:banner_id", intc.RequireAdminAction("banner:modify"), adminHandler.ModifyBanner())
		adminAuthApiRouter.DELETE("/banners/:banner_id", intc.RequireAdminAction("banner:delete"), adminHandler.DeleteBanner())
		adminAuthApiRouter.GET("/banners", intc.RequireAdminAction("banner:view"), adminHandler.ListBanners())

		// 渠道管理
		adminAuthApiRouter.POST("/channels", intc.RequireAdminAction("channel:create"), adminHandler.CreateChannel())
		adminAuthApiRouter.PUT("/channels/:channel_id", intc.RequireAdminAction("channel:modify"), adminHandler.ModifyChannel())
		adminAuthApiRouter.DELETE("/channels/:channel_id", intc.RequireAdminAction("channel:delete"), adminHandler.DeleteChannel())
		adminAuthApiRouter.GET("/channels", intc.RequireAdminAction("channel:view"), adminHandler.ListChannels())
		adminAuthApiRouter.GET("/channels/:channel_id/stats", intc.RequireAdminAction("channel:view"), adminHandler.ChannelStats())

		// 抖店订单管理
		adminAuthApiRouter.GET("/douyin/config", adminHandler.GetDouyinConfig())
		adminAuthApiRouter.PUT("/douyin/config", adminHandler.SaveDouyinConfig())
		adminAuthApiRouter.GET("/douyin/orders", adminHandler.ListDouyinOrders())
		adminAuthApiRouter.POST("/douyin/sync", adminHandler.SyncDouyinOrders())
		// 抖店商品奖励规则
		adminAuthApiRouter.GET("/douyin/product-rewards", adminHandler.ListDouyinProductRewards())
		adminAuthApiRouter.POST("/douyin/product-rewards", adminHandler.CreateDouyinProductReward())
		adminAuthApiRouter.PUT("/douyin/product-rewards/:id", adminHandler.UpdateDouyinProductReward())
		adminAuthApiRouter.DELETE("/douyin/product-rewards/:id", adminHandler.DeleteDouyinProductReward())

		// 系统配置KV
		adminAuthApiRouter.GET("/system/configs", adminHandler.ListSystemConfigs())
		adminAuthApiRouter.POST("/system/configs", adminHandler.UpsertSystemConfig())
		adminAuthApiRouter.PUT("/system/configs/:id", adminHandler.ModifySystemConfig())
		adminAuthApiRouter.DELETE("/system/configs/:id", adminHandler.DeleteSystemConfig())

		// 用户管理
		adminAuthApiRouter.GET("/users", intc.RequireAdminAction("user:view"), adminHandler.ListAppUsers())
		adminAuthApiRouter.GET("/users/:user_id/invites", intc.RequireAdminAction("user:view"), adminHandler.ListUserInvites())
		adminAuthApiRouter.GET("/users/:user_id/orders", intc.RequireAdminAction("user:view"), adminHandler.ListUserOrders())
		adminAuthApiRouter.GET("/users/:user_id/coupons", intc.RequireAdminAction("user:view"), adminHandler.ListUserCoupons())
		adminAuthApiRouter.GET("/users/:user_id/coupons/:user_coupon_id/usage", intc.RequireAdminAction("user:view"), adminHandler.ListUserCouponUsage())
		adminAuthApiRouter.GET("/users/:user_id/points", intc.RequireAdminAction("user:view"), adminHandler.ListUserPoints())
		adminAuthApiRouter.GET("/users/:user_id/points/balance", intc.RequireAdminAction("user:view"), adminHandler.GetUserPointsBalance())
		adminAuthApiRouter.POST("/users/:user_id/points/add", intc.RequireAdminAction("user:points:add"), adminHandler.AddUserPoints())
		adminAuthApiRouter.POST("/users/:user_id/coupons/add", intc.RequireAdminAction("user:coupons:add"), adminHandler.AddUserCoupon())
		adminAuthApiRouter.POST("/users/:user_id/coupons/:user_coupon_id/void", intc.RequireAdminAction("user:coupons:void"), adminHandler.VoidUserCoupon())
		adminAuthApiRouter.POST("/users/:user_id/rewards/grant", intc.RequireAdminAction("user:rewards:grant"), adminHandler.GrantReward())
		adminAuthApiRouter.GET("/users/:user_id/titles", intc.RequireAdminAction("user:view"), adminHandler.ListUserTitles())
		adminAuthApiRouter.GET("/users/:user_id/stats/profit_loss", intc.RequireAdminAction("user:view"), adminHandler.GetUserProfitLossTrend())
		adminAuthApiRouter.GET("/users/:user_id/profile", intc.RequireAdminAction("user:view"), adminHandler.GetUserProfile())

		adminAuthApiRouter.POST("/users/:user_id/token", intc.RequireAdminAction("user:token:issue"), adminHandler.IssueUserToken())
		adminAuthApiRouter.POST("/users/batch/points/add", intc.RequireAdminAction("user:points:batch:add"), adminHandler.BatchAddUserPoints())
		adminAuthApiRouter.POST("/users/batch/coupons/add", intc.RequireAdminAction("user:coupons:batch:add"), adminHandler.BatchAddUserCoupons())
		adminAuthApiRouter.POST("/users/batch/rewards/grant", intc.RequireAdminAction("user:rewards:batch:grant"), adminHandler.BatchGrantUserRewards())
		adminAuthApiRouter.GET("/users/:user_id/inventory", intc.RequireAdminAction("user:view"), adminHandler.ListUserInventory())
		adminAuthApiRouter.POST("/users/:user_id/inventory/:inventory_id/void", intc.RequireAdminAction("user:inventory:void"), adminHandler.VoidUserInventory())
		adminAuthApiRouter.GET("/users/:user_id/item_cards", adminHandler.ListUserItemCards())
		adminAuthApiRouter.POST("/users/:user_id/item_cards/:user_item_card_id/void", adminHandler.VoidUserItemCard())
		// 已移除：为指定用户签发APP令牌接口（未被前端使用）
		// 系统称号与分配
		adminAuthApiRouter.GET("/system_titles", intc.RequireAdminAction("title:view"), adminHandler.ListSystemTitles())
		adminAuthApiRouter.POST("/users/:user_id/titles", intc.RequireAdminAction("title:assign"), adminHandler.AssignUserTitle())
		adminAuthApiRouter.POST("/system_titles", intc.RequireAdminAction("title:create"), adminHandler.CreateSystemTitle())
		adminAuthApiRouter.PUT("/system_titles/:title_id", intc.RequireAdminAction("title:modify"), adminHandler.ModifySystemTitle())
		adminAuthApiRouter.DELETE("/system_titles/:title_id", intc.RequireAdminAction("title:delete"), adminHandler.DeleteSystemTitle())
		adminAuthApiRouter.GET("/system_titles/:title_id/effects", intc.RequireAdminAction("title:view"), adminHandler.ListSystemTitleEffects())
		adminAuthApiRouter.POST("/system_titles/:title_id/effects", intc.RequireAdminAction("title:effect:create"), adminHandler.CreateSystemTitleEffect())
		adminAuthApiRouter.PUT("/system_titles/:title_id/effects/:effect_id", intc.RequireAdminAction("title:effect:modify"), adminHandler.ModifySystemTitleEffect())
		adminAuthApiRouter.DELETE("/system_titles/:title_id/effects/:effect_id", intc.RequireAdminAction("title:effect:delete"), adminHandler.DeleteSystemTitleEffect())

		// 小程序二维码生成
		adminAuthApiRouter.POST("/miniapp/qrcode", adminHandler.GenerateMiniAppQRCode())

		// 小程序发货信息管理（虚拟发货）
		adminAuthApiRouter.POST("/miniapp/shipping/set_jump_path", adminHandler.SetMiniAppMsgJumpPath())
		adminAuthApiRouter.POST("/miniapp/shipping/upload_virtual", adminHandler.UploadVirtualShippingForTransaction())

		// 道具卡管理
		adminAuthApiRouter.POST("/system_item_cards", intc.RequireAdminAction("itemcard:create"), adminHandler.CreateSystemItemCard())
		adminAuthApiRouter.PUT("/system_item_cards/:item_card_id", intc.RequireAdminAction("itemcard:modify"), adminHandler.ModifySystemItemCard())
		adminAuthApiRouter.DELETE("/system_item_cards/:item_card_id", intc.RequireAdminAction("itemcard:delete"), adminHandler.DeleteSystemItemCard())
		adminAuthApiRouter.GET("/system_item_cards", intc.RequireAdminAction("itemcard:view"), adminHandler.ListSystemItemCards())
		// 优惠券管理
		adminAuthApiRouter.POST("/system_coupons", intc.RequireAdminAction("coupon:create"), adminHandler.CreateSystemCoupon())
		adminAuthApiRouter.PUT("/system_coupons/:coupon_id", intc.RequireAdminAction("coupon:modify"), adminHandler.ModifySystemCoupon())
		adminAuthApiRouter.DELETE("/system_coupons/:coupon_id", intc.RequireAdminAction("coupon:delete"), adminHandler.DeleteSystemCoupon())
		adminAuthApiRouter.GET("/system_coupons", intc.RequireAdminAction("coupon:view"), adminHandler.ListSystemCoupons())
		adminAuthApiRouter.POST("/users/:user_id/item_cards", adminHandler.AssignUserItemCard())

		// 次数卡管理
		adminAuthApiRouter.POST("/game-passes/grant", adminHandler.GrantGamePass())
		adminAuthApiRouter.GET("/game-passes/list", adminHandler.ListGamePasses())
		adminAuthApiRouter.GET("/users/:user_id/game-passes", adminHandler.GetUserGamePasses())
		adminAuthApiRouter.GET("/activities/:activity_id/game-passes/check", adminHandler.CheckActivityGamePasses())

		// 次数卡套餐管理
		adminAuthApiRouter.GET("/game-pass-packages", adminHandler.ListGamePassPackages())
		adminAuthApiRouter.POST("/game-pass-packages", adminHandler.CreateGamePassPackage())
		adminAuthApiRouter.PUT("/game-pass-packages/:package_id", adminHandler.ModifyGamePassPackage())
		adminAuthApiRouter.DELETE("/game-pass-packages/:package_id", adminHandler.DeleteGamePassPackage())

		// 对对碰卡牌类型管理
		adminAuthApiRouter.GET("/matching_card_types", adminHandler.ListMatchingCardTypes())
		adminAuthApiRouter.POST("/matching_card_types", adminHandler.CreateMatchingCardType())
		adminAuthApiRouter.PUT("/matching_card_types/:id", adminHandler.ModifyMatchingCardType())
		adminAuthApiRouter.DELETE("/matching_card_types/:id", adminHandler.DeleteMatchingCardType())
		adminAuthApiRouter.GET("/matching/audit/:order_no", adminHandler.GetMatchingAudit())

		// 游戏资格管理
		adminAuthApiRouter.GET("/users/:user_id/game_tickets", gameHandler.ListUserTickets())
		adminAuthApiRouter.POST("/users/:user_id/game_tickets", gameHandler.GrantUserTicket())

		// 发货统计
		adminAuthApiRouter.GET("/ops_shipping_stats", intc.RequireAdminAction("ops:shipping:view"), adminHandler.ListShippingStats())
		adminAuthApiRouter.GET("/ops_shipping_stats/:id", intc.RequireAdminAction("ops:shipping:view"), adminHandler.GetShippingStat())
		adminAuthApiRouter.POST("/ops_shipping_stats", intc.RequireAdminAction("ops:shipping:write"), adminHandler.CreateShippingStat())
		adminAuthApiRouter.PUT("/ops_shipping_stats/:id", intc.RequireAdminAction("ops:shipping:write"), adminHandler.ModifyShippingStat())
		adminAuthApiRouter.DELETE("/ops_shipping_stats/:id", intc.RequireAdminAction("ops:shipping:write"), adminHandler.DeleteShippingStat())

		// 发货订单管理
		adminAuthApiRouter.GET("/shipping/orders", intc.RequireAdminAction("shipping:view"), adminHandler.ListShippingOrders())
		adminAuthApiRouter.GET("/shipping/orders/:id", intc.RequireAdminAction("shipping:view"), adminHandler.GetShippingOrderDetail())
		adminAuthApiRouter.PUT("/shipping/orders/batch", intc.RequireAdminAction("shipping:modify"), adminHandler.UpdateShippingBatch())

		adminAuthApiRouter.POST("/pay/refunds", intc.RequireAdminAction("refund:create"), adminHandler.CreateRefund())
		adminAuthApiRouter.GET("/pay/refunds", intc.RequireAdminAction("refund:view"), adminHandler.ListRefunds())
		adminAuthApiRouter.GET("/pay/refunds/:refund_no", intc.RequireAdminAction("refund:view"), adminHandler.GetRefundDetail())
		adminAuthApiRouter.GET("/lottery/issues/:issue_id/participants", adminHandler.GetIssueParticipants())
		adminAuthApiRouter.POST("/lottery/issues/:issue_id/settle", adminHandler.SettleIssue())
		adminAuthApiRouter.POST("/lottery/issues/:issue_id/simulate", adminHandler.SimulateIssue())
		adminAuthApiRouter.GET("/ichiban/activities/:activity_id/issues/:issue_id/slots", adminHandler.ListIchibanSlots())
		adminAuthApiRouter.GET("/ichiban/issues/:issue_id/slot/:slot_index", adminHandler.GetIchibanSlotDetail())

		adminAuthApiRouter.POST("/activities/:activity_id/commitment/generate", adminHandler.GenerateActivityCommitmentGeneral())
		adminAuthApiRouter.GET("/activities/:activity_id/commitment/summary", adminHandler.GetActivityCommitmentSummaryGeneral())
		adminAuthApiRouter.POST("/pay/bills/import", adminHandler.ImportPaymentBill())
		adminAuthApiRouter.GET("/pay/bills/diff", adminHandler.ListPaymentBillDiff())
		adminAuthApiRouter.GET("/pay/orders", intc.RequireAdminAction("order:view"), adminHandler.ListPayOrders())
		adminAuthApiRouter.GET("/pay/orders/:order_no", intc.RequireAdminAction("order:view"), adminHandler.GetPayOrderDetail())
		adminAuthApiRouter.PUT("/pay/orders/:order_no/remark", intc.RequireAdminAction("order:modify"), adminHandler.UpdateOrderRemark())
		adminAuthApiRouter.POST("/pay/orders/:order_no/cancel", intc.RequireAdminAction("order:cancel"), adminHandler.CancelOrder())
		adminAuthApiRouter.PUT("/pay/orders/:order_no/consume", intc.RequireAdminAction("order:consume"), adminHandler.ConsumeOrder())
		adminAuthApiRouter.POST("/pay/orders/:order_no/miniapp_shipping", intc.RequireAdminAction("order:miniapp_shipping"), adminHandler.UploadMiniAppVirtualShippingForOrder())
		adminAuthApiRouter.GET("/pay/orders/export", intc.RequireAdminAction("order:export"), adminHandler.ExportPayOrders())
		// 订单审计快照
		adminAuthApiRouter.GET("/orders/:order_id/snapshots", intc.RequireAdminAction("order:view"), adminHandler.GetOrderSnapshots())
		adminAuthApiRouter.POST("/orders/:order_id/rollback", intc.RequireAdminAction("order:rollback"), adminHandler.RollbackOrder())
		// 通用上传
		systemApiRouter.POST("/common/upload/wangeditor", commonHandler.UploadWangEditorImage())
		systemApiRouter.POST("/menu/ensure_titles", adminHandler.EnsureTitlesMenu())
	}

	// 系统管理：用户/角色/菜单
	{

		systemApiRouter.GET("/user/list", adminHandler.ListUsers())
		systemApiRouter.POST("/user", adminHandler.CreateUser())
		systemApiRouter.GET("/role/list", adminHandler.ListRoles())
		systemApiRouter.GET("/v3/system/menus/simple", adminHandler.ListSimpleMenus())
		systemApiRouter.POST("/role", adminHandler.CreateRole())
		systemApiRouter.PUT("/role/:role_id", adminHandler.ModifyRole())
		systemApiRouter.DELETE("/role/:role_id", adminHandler.DeleteRole())
		systemApiRouter.POST("/role/:role_id/users", adminHandler.AssignRoleUsers())
		systemApiRouter.GET("/role/:role_id/users", adminHandler.ListRoleUsers())
		systemApiRouter.DELETE("/role/:role_id/users/:admin_id", adminHandler.RemoveRoleUser())
		systemApiRouter.POST("/menu", adminHandler.CreateMenu())
		systemApiRouter.PUT("/menu/:menu_id", adminHandler.ModifyMenu())
		systemApiRouter.DELETE("/menu/:menu_id", adminHandler.DeleteMenu())
		systemApiRouter.GET("/menu/:menu_id/actions", adminHandler.ListMenuActions())
		systemApiRouter.POST("/menu/:menu_id/actions", adminHandler.CreateMenuActions())
		systemApiRouter.DELETE("/menu/:menu_id/actions/:action_id", adminHandler.DeleteMenuAction())
		systemApiRouter.POST("/role/:role_id/menus", adminHandler.AssignRoleMenus())
		systemApiRouter.POST("/role/:role_id/actions", adminHandler.AssignRoleActions())
		systemApiRouter.GET("/system/recycle", adminHandler.ListRecycle())
		systemApiRouter.POST("/system/recycle/restore", adminHandler.RestoreRecycle())
		systemApiRouter.DELETE("/system/recycle", adminHandler.ForceDeleteRecycle())
	}

	// APP 端公开接口路由组
	appPublicApiRouter := mux.Group("/api/app")
	{
		appPublicApiRouter.GET("/activities", activityHandler.ListActivities())
		appPublicApiRouter.GET("/activities/:activity_id", activityHandler.GetActivityDetail())
		appPublicApiRouter.GET("/activities/:activity_id/issues", activityHandler.ListActivityIssues())
		appPublicApiRouter.GET("/activities/:activity_id/issues/:issue_id/rewards", activityHandler.ListIssueRewards())
		appPublicApiRouter.GET("/activities/:activity_id/issues/:issue_id/draw_logs", activityHandler.ListDrawLogs())
		appPublicApiRouter.GET("/activities/:activity_id/issues/:issue_id/draw_logs_grouped", activityHandler.ListDrawLogsByLevel())

		// APP 端轮播图
		appPublicApiRouter.GET("/banners", appapi.NewBanner(logger, db).ListBannersForApp())
		appPublicApiRouter.GET("/notices", appapi.NewNotice(logger, db).ListNoticesForApp())
		appPublicApiRouter.GET("/categories", appapi.NewCategory(logger, db).ListCategoriesForApp())

		// 登录保持公开
		appPublicApiRouter.POST("/users/weixin/login", userHandler.WeixinLogin())
		appPublicApiRouter.POST("/users/douyin/login", userHandler.DouyinLogin())
		appPublicApiRouter.POST("/address-share/submit", userHandler.SubmitAddressShare())
		appPublicApiRouter.GET("/matching/card_types", activityHandler.ListMatchingCardTypes())

		// 短信登录
		appPublicApiRouter.POST("/sms/send-code", userHandler.SendSmsCode())
		appPublicApiRouter.POST("/sms/login", userHandler.SmsLogin())

		// 公共工具
		appPublicApiRouter.POST("/common/openid", commonHandler.GetOpenID())
	}

	// APP 端认证接口路由组
	appAuthApiRouter := mux.Group("/api/app", core.WrapAuthHandler(intc.AppTokenAuthVerify))
	{
		appAuthApiRouter.PUT("/users/:user_id", userHandler.ModifyUser())
		appAuthApiRouter.GET("/users/profile", userHandler.GetUserProfile())
		appAuthApiRouter.GET("/users/info", userHandler.GetUserProfile()) // 别名，保持前端兼容性
		appAuthApiRouter.GET("/users/:user_id/orders", userHandler.ListUserOrders())
		appAuthApiRouter.GET("/users/:user_id/coupons", userHandler.ListUserCoupons())
		appAuthApiRouter.GET("/users/:user_id/coupons/stats", userHandler.GetUserCouponStats())
		appAuthApiRouter.GET("/users/:user_id/coupons/:user_coupon_id/usage", userHandler.ListUserCouponUsage())
		appAuthApiRouter.GET("/users/:user_id/points", userHandler.ListUserPoints())
		appAuthApiRouter.GET("/users/:user_id/points/balance", userHandler.GetUserPointsBalance())
		appAuthApiRouter.GET("/users/:user_id/stats", userHandler.GetUserStats())
		appAuthApiRouter.POST("/users/:user_id/phone/bind", userHandler.BindPhone())
		appAuthApiRouter.POST("/users/:user_id/douyin/phone/bind", userHandler.DouyinBindPhone())
		appAuthApiRouter.POST("/users/douyin/bind", userHandler.BindDouyinOrder())
		appAuthApiRouter.GET("/users/:user_id/invites", userHandler.ListUserInvites())
		appAuthApiRouter.GET("/users/:user_id/inventory", userHandler.ListUserInventory())
		appAuthApiRouter.GET("/users/:user_id/shipments", userHandler.ListUserShipments())
		appAuthApiRouter.GET("/users/:user_id/item_cards", userHandler.ListUserItemCards())
		appAuthApiRouter.GET("/users/:user_id/item_cards/uses", userHandler.ListUserItemCardUses())
		appAuthApiRouter.POST("/users/:user_id/addresses", userHandler.AddUserAddress())
		appAuthApiRouter.GET("/users/:user_id/addresses", userHandler.ListUserAddresses())
		appAuthApiRouter.PUT("/users/:user_id/addresses/:address_id/default", userHandler.SetDefaultUserAddress())
		appAuthApiRouter.PUT("/users/:user_id/addresses/:address_id", userHandler.UpdateUserAddress())
		appAuthApiRouter.DELETE("/users/:user_id/addresses/:address_id", userHandler.DeleteUserAddress())

		appAuthApiRouter.POST("/pay/wechat/jsapi/preorder", userHandler.WechatJSAPIPreorder())
		appAuthApiRouter.POST("/lottery/join", activityHandler.JoinLottery())

		// 任务中心 APP 端
		appAuthApiRouter.GET("/task-center/tasks", taskCenterHandler.ListTasksForApp())
		appAuthApiRouter.GET("/task-center/tasks/:id/progress/:user_id", taskCenterHandler.GetTaskProgressForApp())
		appAuthApiRouter.POST("/task-center/tasks/:id/claim/:user_id", taskCenterHandler.ClaimTaskTierForApp())

		appAuthApiRouter.GET("/activities/:activity_id/issues/:issue_id/choices", activityHandler.ListIssueChoices())
		appAuthApiRouter.POST("/orders/test/create", userHandler.CreateTestOrder())
		appAuthApiRouter.GET("/orders/:order_id", userHandler.GetOrderDetail())
		appAuthApiRouter.POST("/orders/:order_id/cancel", userHandler.CancelOrder())
		appAuthApiRouter.GET("/products", appapi.NewProduct(logger, db, userSvc).ListProductsForApp())
		appAuthApiRouter.GET("/products/:id", appapi.NewProduct(logger, db, userSvc).GetProductDetailForApp())
		appAuthApiRouter.GET("/store/items", appapi.NewStore(logger, db, userSvc).ListStoreItemsForApp())
		appAuthApiRouter.GET("/lottery/result", activityHandler.LotteryResultByOrder())

		// 对对碰游戏
		appAuthApiRouter.POST("/matching/preorder", activityHandler.PreOrderMatchingGame())
		appAuthApiRouter.POST("/matching/check", activityHandler.CheckMatchingGame())
		appAuthApiRouter.GET("/matching/state", activityHandler.GetMatchingGameState())
		appAuthApiRouter.GET("/matching/cards", activityHandler.GetMatchingGameCards()) // 支付成功后获取游戏数据

		// 次数卡
		appAuthApiRouter.GET("/game-passes/available", userHandler.GetGamePasses())
		appAuthApiRouter.GET("/game-passes/packages", userHandler.GetGamePassPackages())
		appAuthApiRouter.POST("/game-passes/purchase", userHandler.PurchaseGamePassPackage())

		// 扫雷游戏
		appAuthApiRouter.GET("/users/:user_id/game_tickets", gameHandler.GetMyTickets())
		appAuthApiRouter.POST("/games/enter", gameHandler.EnterGame())

		appAuthApiRouter.POST("/users/:user_id/inventory/address-share/create", userHandler.CreateAddressShare())
		appAuthApiRouter.POST("/users/:user_id/inventory/address-share/revoke", userHandler.RevokeAddressShare())
		appAuthApiRouter.POST("/users/:user_id/inventory/request-shipping", userHandler.RequestShippingBatch())
		appAuthApiRouter.POST("/users/:user_id/inventory/cancel-shipping", userHandler.CancelShipping())
		appAuthApiRouter.POST("/users/:user_id/inventory/redeem", userHandler.RedeemInventoryToPoints())
		appAuthApiRouter.POST("/users/:user_id/points/redeem-coupon", userHandler.RedeemPointsToCoupon())
		appAuthApiRouter.POST("/users/:user_id/points/redeem-product", userHandler.RedeemPointsToProduct())
		appAuthApiRouter.POST("/users/:user_id/points/redeem-item-card", userHandler.RedeemPointsToItemCard())
	}
	// 微信支付平台回调(无需鉴权)
	mux.Group("/api/pay").POST("/wechat/notify", payHandler.WechatNotify())
	return mux, cancel, nil
}
