//go:build ignore

package main

import (
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/glebarez/sqlite"
	"github.com/user-management-system/internal/auth"
	"github.com/user-management-system/internal/config"
	"github.com/user-management-system/internal/domain"
	"gorm.io/gorm"
)

func main() {
	username := strings.TrimSpace(os.Getenv("UMS_ADMIN_USERNAME"))
	password := os.Getenv("UMS_ADMIN_PASSWORD")
	email := strings.TrimSpace(os.Getenv("UMS_ADMIN_EMAIL"))
	resetPassword := strings.EqualFold(strings.TrimSpace(os.Getenv("UMS_ADMIN_RESET_PASSWORD")), "true")

	if username == "" || password == "" {
		log.Fatal("UMS_ADMIN_USERNAME and UMS_ADMIN_PASSWORD are required")
	}

	db, err := gorm.Open(sqlite.Open(resolveDBPath()), &gorm.Config{})
	if err != nil {
		log.Fatal("open db:", err)
	}

	var adminRole domain.Role
	if err := db.Where("code = ?", "admin").First(&adminRole).Error; err != nil {
		log.Fatal("admin role not found:", err)
	}

	var user domain.User
	err = db.Where("username = ?", username).First(&user).Error
	switch {
	case err == nil:
		if email != "" {
			user.Email = &email
		}
		user.Status = domain.UserStatusActive
		if resetPassword {
			passwordHash, hashErr := auth.HashPassword(password)
			if hashErr != nil {
				log.Fatal("hash password:", hashErr)
			}
			user.Password = passwordHash
		}
		if saveErr := db.Save(&user).Error; saveErr != nil {
			log.Fatal("update admin:", saveErr)
		}
	case err == gorm.ErrRecordNotFound:
		passwordHash, hashErr := auth.HashPassword(password)
		if hashErr != nil {
			log.Fatal("hash password:", hashErr)
		}

		user = domain.User{
			Username: username,
			Email:    stringPtr(email),
			Password: passwordHash,
			Status:   domain.UserStatusActive,
			Nickname: username,
		}
		if createErr := db.Create(&user).Error; createErr != nil {
			log.Fatal("create admin:", createErr)
		}
	default:
		log.Fatal("query admin:", err)
	}

	var binding domain.UserRole
	bindingErr := db.Where("user_id = ? AND role_id = ?", user.ID, adminRole.ID).First(&binding).Error
	if bindingErr == gorm.ErrRecordNotFound {
		if err := db.Create(&domain.UserRole{UserID: user.ID, RoleID: adminRole.ID}).Error; err != nil {
			log.Fatal("assign admin role:", err)
		}
	} else if bindingErr != nil {
		log.Fatal("query admin role binding:", bindingErr)
	}

	fmt.Printf("admin initialized: username=%s user_id=%d role_id=%d\n", user.Username, user.ID, adminRole.ID)
}

func stringPtr(value string) *string {
	if strings.TrimSpace(value) == "" {
		return nil
	}
	return &value
}

func resolveDBPath() string {
	if path := strings.TrimSpace(os.Getenv("UMS_DATABASE_SQLITE_PATH")); path != "" {
		return path
	}

	cfg, err := config.Load(resolveConfigPath())
	if err == nil && strings.EqualFold(strings.TrimSpace(cfg.Database.Type), "sqlite") {
		if path := strings.TrimSpace(cfg.Database.SQLite.Path); path != "" {
			return path
		}
	}

	return "./data/user_management.db"
}

func resolveConfigPath() string {
	if path := strings.TrimSpace(os.Getenv("UMS_CONFIG_PATH")); path != "" {
		return path
	}
	return "./configs/config.yaml"
}
