package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"ai-myopia-prevention/api/handlers"
	"ai-myopia-prevention/db/models"
	"ai-myopia-prevention/internal/middleware"
)

func main() {
	fmt.Println("启明计划 - AI近视防控系统 后端服务启动中...")

	// 初始化Gin路由器
	r := gin.Default()

	// 初始化数据库连接
	db, err := initDatabase()
	if err != nil {
		log.Fatal("数据库连接失败:", err)
	}

	// 禁用外键约束自动创建
	db = db.Set("gorm:table_options", "ENGINE=InnoDB")
	
	// 自动迁移数据库表结构 (禁用外键)
	err = migrateDatabase(db)
	if err != nil {
		log.Fatal("数据库迁移失败:", err)
	}

	// 初始化服务
	authService := handlers.NewAuthService(db)
	detectionService := handlers.NewDetectionService(db)

	// 设置路由
	setupRoutes(r, authService, detectionService)

	// 启动服务器
	port := "8080"
	log.Printf("服务器将在 :%s 端口启动", port)
	if err := r.Run(":" + port); err != nil {
		log.Fatal("服务器启动失败:", err)
	}
}

// initDatabase 初始化数据库连接
func initDatabase() (*gorm.DB, error) {
	// 从环境变量读取数据库配置
	dbHost := os.Getenv("DB_HOST")
	if dbHost == "" {
		dbHost = "mysql" // Docker 网络中的默认主机名
	}
	dbUser := os.Getenv("DB_USER")
	if dbUser == "" {
		dbUser = "myopia_user"
	}
	dbPassword := os.Getenv("DB_PASSWORD")
	if dbPassword == "" {
		dbPassword = "MyopiaTest2026!"
	}
	dbName := os.Getenv("DB_NAME")
	if dbName == "" {
		dbName = "ai_myopia"
	}
	
	dsn := fmt.Sprintf("%s:%s@tcp(%s:3306)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		dbUser, dbPassword, dbHost, dbName)
	
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		// 配置日志记录
		Logger: nil, // 在生产环境中可以使用gorm/logger.Default
	})
	
	if err != nil {
		return nil, fmt.Errorf("连接数据库失败: %v", err)
	}

	// 设置连接池
	sqlDB, err := db.DB()
	if err != nil {
		return nil, fmt.Errorf("获取底层sql.DB失败: %v", err)
	}
	
	// 设置连接池参数
	sqlDB.SetMaxIdleConns(10)
	sqlDB.SetMaxOpenConns(100)
	sqlDB.SetConnMaxLifetime(time.Hour)

	return db, nil
}

// migrateDatabase 数据库表结构迁移
func migrateDatabase(db *gorm.DB) error {
	// 自动迁移数据库表结构 (禁用外键)
	// 注意：在生产环境中，通常使用迁移文件而不是自动迁移
	err := db.Migrator().DropTable(
	)
	err = db.AutoMigrate(
		&models.User{},
		&models.Student{},
		&models.Parent{},
		&models.Teacher{},
		&models.School{},
		&models.Class{},
		&models.UserAccount{},
		&models.DetectionTask{},
		&models.Detection{},
		&models.DetectionReport{},
		&models.Alert{},
		&models.AlertConfig{},
		&models.AlertSummary{},
		&models.Device{},
		&models.DeviceConfig{},
		&models.DeviceLog{},
		&models.DeviceStatusInfo{},
		&models.DeviceCommand{},
		&models.DeviceMessage{},
		&models.DeviceHeartbeat{},
		&models.DeviceGroup{},
		&models.DeviceGroupRelation{},
		&models.DeviceMaintenance{},
	)
	
	if err != nil {
		return fmt.Errorf("数据库迁移失败: %v", err)
	}

	fmt.Println("数据库表结构迁移完成")
	return nil
}

// setupRoutes 设置路由
func setupRoutes(r *gin.Engine, auth *handlers.AuthService, detection *handlers.DetectionService) {
	// 健康检查端点
	r.GET("/health", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"status":  "ok",
			"service": "ai-myopia-prevention-backend",
			"time":    time.Now().Unix(),
		})
	})

	// API版本路由组
	v1 := r.Group("/api/v1")
	{
		// 认证相关路由
		authGroup := v1.Group("/auth")
		{
			authGroup.POST("/login", auth.Login)
			authGroup.POST("/register", auth.Register)
			authGroup.GET("/profile", middleware.JWTAuthMiddleware(), auth.GetProfile)
			authGroup.PUT("/profile", middleware.JWTAuthMiddleware(), auth.UpdateProfile)
			authGroup.PUT("/password", middleware.JWTAuthMiddleware(), auth.ChangePassword)
		}

		// 检测相关路由
		detectionGroup := v1.Group("/detections")
		{
			detectionGroup.POST("/start", middleware.JWTAuthMiddleware(), middleware.RBACMiddleware("teacher", "admin"), detection.StartDetection)
			detectionGroup.POST("/submit", middleware.JWTAuthMiddleware(), middleware.RBACMiddleware("student", "teacher", "admin"), detection.SubmitDetection)
			detectionGroup.GET("/report/:detection_id/student/:student_id", middleware.JWTAuthMiddleware(), detection.GetDetectionReport)
			detectionGroup.GET("/history", middleware.JWTAuthMiddleware(), detection.GetDetectionHistory)
			detectionGroup.GET("/class/:class_id/stats", middleware.JWTAuthMiddleware(), middleware.RBACMiddleware("teacher", "admin"), detection.GetClassStats)
		}

		// 学生相关路由
		studentGroup := v1.Group("/students")
		{
			studentGroup.Use(middleware.JWTAuthMiddleware())
			// 学生只能访问自己的信息，家长可以访问孩子的信息，老师可以访问班级学生信息，管理员可以访问所有
			// TODO: 实现学生相关API
		}

		// 班级相关路由
		classGroup := v1.Group("/classes")
		{
			classGroup.Use(middleware.JWTAuthMiddleware())
			// 只有老师和管理员可以访问班级信息
			// TODO: 实现班级相关API
		}

		// 预警相关路由
		alertGroup := v1.Group("/alerts")
		{
			alertGroup.Use(middleware.JWTAuthMiddleware())
			// 学生可以查看自己的预警，家长可以查看孩子的预警，老师可以查看班级预警，管理员可以查看所有
			// TODO: 实现预警相关API
		}

		// 训练相关路由
		trainingGroup := v1.Group("/training")
		{
			trainingGroup.Use(middleware.JWTAuthMiddleware())
			// 学生可以查看自己的训练，家长可以查看孩子的训练，老师可以查看班级训练，管理员可以查看所有
			// TODO: 实现训练相关API
		}

		// 设备相关路由
		deviceGroup := v1.Group("/devices")
		{
			deviceGroup.Use(middleware.JWTAuthMiddleware(), middleware.RBACMiddleware("admin"))
			// 只有管理员可以管理设备
			// TODO: 实现设备相关API
		}
	}

	// 为静态文件提供服务
	r.Static("/static", "./static")

	// 为上传文件提供服务
	r.Static("/uploads", "./uploads")

	fmt.Println("路由设置完成")
}