package main

import (
	"log"

	"metazone.cc/metalab/internal/config"
	"metazone.cc/metalab/internal/model"
	"metazone.cc/metalab/internal/router"
	"metazone.cc/metalab/internal/theme"

	"github.com/gin-gonic/gin"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

func main() {
	// 配置
	cfg := config.Load("config.yaml")

	// 从配置初始化角色系统（OCP：新增角色无需修改源代码）
	model.InitRoles(cfg.Roles.Levels, cfg.Roles.Names, cfg.Roles.Permissions.OperableRoles)

	// 数据库
	db, err := gorm.Open(postgres.Open(cfg.Database.DSN()), &gorm.Config{})
	if err != nil {
		log.Fatalf("连接数据库失败: %v", err)
	}
	if err := db.AutoMigrate(&model.User{}, &model.AuditSubmission{}, &model.SiteSetting{}, &model.Notification{}, &model.Post{}); err != nil {
		log.Fatalf("数据库迁移失败: %v", err)
	}

	// 邮箱唯一索引迁移：从全表唯一改为部分唯一（仅 deleted_at IS NULL 的行）
	// 支持软删除用户邮箱复用
	migrations := []string{
		`DROP INDEX IF EXISTS idx_users_email`,
		`CREATE INDEX IF NOT EXISTS idx_users_email ON users (email)`,
		`CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email_active ON users (email) WHERE deleted_at IS NULL`,
	}
	for _, m := range migrations {
		if err := db.Exec(m).Error; err != nil {
			log.Fatalf("数据库迁移失败 (%s): %v", m, err)
		}
	}
	log.Println("数据库连接成功")

	// Gin 模式
	gin.SetMode(cfg.Server.Mode)

	r := gin.Default()

	// 模板加载（前端主题 + 管理后台）
	tmpl, err := theme.LoadTemplates(
		theme.TemplateRoot{Dir: "templates/MetaLab-2026/html", Prefix: ""},
		theme.TemplateRoot{Dir: "templates/admin/html", Prefix: "admin/"},
	)
	if err != nil {
		panic("加载模板失败: " + err.Error())
	}
	r.SetHTMLTemplate(tmpl)

	// 静态资源
	r.Static("/static", "./templates/MetaLab-2026/static")
	r.Static("/admin/static", "./templates/admin/static")
	r.Static("/shared/static", "./templates/shared/static")
	r.Static("/uploads/avatars", "./storage/uploads/avatars")
	r.Static("/uploads/posts", "./storage/uploads/posts")

	// 站点设置管理器（DB 持久化 + 内存缓存）
	siteSettings, err := config.NewSiteSettings(db)
	if err != nil {
		log.Fatalf("初始化站点设置失败: %v", err)
	}

	// 路由注册
	router.Setup(r, db, cfg, siteSettings)

	// 启动
	log.Printf("MetaZone.FAN 启动于 0.0.0.0:%s", cfg.Server.Port)
	r.Run("0.0.0.0:" + cfg.Server.Port)
}
