//
// Copyright (C) 2024 veypi <i@veypi.com>
// 2024-09-20 16:10:16
// Distributed under terms of the MIT license.
//

package models

import (
	"fmt"
	"time"

	"github.com/veypi/vbase/cfg"
	"github.com/veypi/vbase/libs/crypto"
	"github.com/veypi/vigo"
	"github.com/veypi/vigo/contrib/event"
)

var AllModels = &vigo.ModelList{}

func init() {
	// 注册所有模型
	AllModels.Add(&User{})
	AllModels.Add(&Identity{})
	AllModels.Add(&Session{})

	// Auth 模块模型
	AllModels.Add(&Permission{})
	AllModels.Add(&Role{})
	AllModels.Add(&UserRole{})

	// OAuth 模型
	AllModels.Add(&OAuthClient{})
	AllModels.Add(&OAuthAuthorizationCode{})
	AllModels.Add(&OAuthToken{})

	// 配置 & 验证码 & 邮件
	AllModels.Add(&Setting{})
	AllModels.Add(&VerificationCode{})
	AllModels.Add(&EmailLog{})
	AllModels.Add(&OAuthProvider{})
	event.Add("vb.init.settings", InitSettings)
	event.Add("vb.init.oauth", InitOAuthProviders)
	event.Add("vb.init.admin", initAdminUser, event.After("vb.init.auth"))
}

func Migrate() error {
	return AllModels.AutoMigrate(cfg.DB())
}

func Drop() error {
	return AllModels.AutoDrop(cfg.DB())
}

// initAdminUser 如果用户表为空且配置了 init_admin，则自动创建管理员
func initAdminUser() error {
	db := cfg.DB()

	// 检查用户表是否为空
	var userCount int64
	if err := db.Model(&User{}).Count(&userCount).Error; err != nil {
		return err
	}

	// 已有用户，跳过
	if userCount > 0 {
		return nil
	}

	// 检查 init_admin 配置
	adminCfg := cfg.Global.InitAdmin
	if adminCfg.Username == "" || adminCfg.Password == "" {
		// 未配置初始管理员，跳过
		return nil
	}

	// 查找 admin 角色
	var adminRole Role
	if err := db.Where("code = ?", RoleCodeAdmin).First(&adminRole).Error; err != nil {
		return fmt.Errorf("admin role not found, please ensure roles are initialized: %w", err)
	}

	// 哈希密码（使用默认 bcrypt cost = 12）
	hashedPassword, err := crypto.HashPassword(adminCfg.Password, 12)
	if err != nil {
		return fmt.Errorf("hash password failed: %w", err)
	}

	// 创建用户
	var email *string
	if adminCfg.Email != "" {
		email = &adminCfg.Email
	}

	now := time.Now()
	user := &User{
		Username:      adminCfg.Username,
		Password:      hashedPassword,
		Email:         email,
		Nickname:      adminCfg.Username,
		Status:        UserStatusActive,
		EmailVerified: email != nil,
		LastLoginAt:   &now,
	}
	user.ID = "admin"

	if err := db.Create(user).Error; err != nil {
		return fmt.Errorf("create admin user failed: %w", err)
	}

	// 授予 admin 角色
	userRole := &UserRole{
		UserID: user.ID,
		RoleID: adminRole.ID,
	}

	if err := db.Create(userRole).Error; err != nil {
		return fmt.Errorf("grant admin role failed: %w", err)
	}

	fmt.Printf("[vbase] Initial admin user '%s' created successfully\n", adminCfg.Username)
	return nil
}
