// Package main 应用程序入口
package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"server/common"
	"server/config"
	_ "server/docs"
	"server/middleware"
	sysController "server/modules/system/controller"
	userController "server/modules/user/controller"
	yxController "server/modules/yx/controller"

	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
)

// @title           艺考招生管理系统 API
// @version         2.0
// @description     提供用户认证、院校专业、历年招生、计算专业的管理接口
// @host            localhost:8080
// @BasePath        /api
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization

func main() {
	// 加载配置
	config.LoadConfig()

	// 初始化日志
	common.InitLogger()
	common.Info("========== 应用启动 ==========")

	// 初始化数据库
	config.InitDB()
	common.Info("数据库初始化完成")

	// 初始化Redis
	config.InitRedis()
	common.Info("Redis初始化完成")

	// 创建 Gin 引擎
	gin.SetMode(gin.ReleaseMode)
	r := gin.New()
	r.Use(gin.Recovery())

	// 请求日志中间件
	r.Use(requestLogMiddleware())

	// 跨域中间件
	r.Use(middleware.CorsMiddleware())

	// Swagger 文档 (需要Basic Auth验证)
	authorized := r.Group("/swagger", gin.BasicAuth(gin.Accounts{
		config.AppConfig.Swagger.User: config.AppConfig.Swagger.Password,
	}))
	authorized.GET("/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

	// API 路由组
	api := r.Group("/api")

	// 中间件顺序: 安全校验 -> 限流 -> 登录鉴权
	api.Use(middleware.SecurityMiddleware())
	api.Use(middleware.RateLimitMiddleware())
	api.Use(middleware.AuthMiddleware())

	// 注册 System 模块路由
	sysController.NewAuthController().RegisterRoutes(api)
	sysController.NewSysUserController().RegisterRoutes(api)

	// 注册 YX 模块路由
	yxController.NewYxSchoolMajorController().RegisterRoutes(api)
	yxController.NewYxHistoryMajorEnrollController().RegisterRoutes(api)
	yxController.NewYxCalculationMajorController().RegisterRoutes(api)
	yxController.NewYxUserScoreController().RegisterRoutes(api)
	yxController.NewYxVolunteerController().RegisterRoutes(api)
	yxController.NewYxVolunteerRecordController().RegisterRoutes(api)

	// 注册 User 模块路由
	userController.NewUserScoreController().RegisterRoutes(api)
	userController.NewAuthController().RegisterRoutes(api)
	userController.NewUserMajorController().RegisterRoutes(api)

	// 创建 HTTP 服务器
	port := config.AppConfig.Server.Port
	if port == 0 {
		port = 8080 // 默认端口
	}
	srv := &http.Server{
		Addr:    fmt.Sprintf(":%d", port),
		Handler: r,
	}

	// 启动服务器
	go func() {
		common.Info("服务器启动: http://localhost:%d", port)
		common.Info("Swagger文档: http://localhost:%d/swagger/index.html", port)
		log.Printf("服务器启动: http://localhost:%d\n", port)
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			common.LogError("启动失败: %s", err)
			log.Fatalf("启动失败: %s\n", err)
		}
	}()

	// 优雅关闭
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	common.Info("正在关闭服务器...")
	log.Println("正在关闭服务器...")

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := srv.Shutdown(ctx); err != nil {
		common.LogError("服务器关闭异常: %v", err)
		log.Fatal("服务器关闭异常:", err)
	}

	// 关闭资源
	config.CloseDB()
	config.CloseRedis()
	common.Info("========== 应用关闭 ==========")
	common.CloseLogger()

	log.Println("服务器已退出")
}

// requestLogMiddleware 请求日志中间件
func requestLogMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now()
		path := c.Request.URL.Path
		method := c.Request.Method

		c.Next()

		latency := time.Since(start)
		status := c.Writer.Status()
		clientIP := c.ClientIP()

		common.Info("%s %s %d %v %s", method, path, status, latency, clientIP)
	}
}
