package models

import (
	"exhibitionCentre/database"
	"exhibitionCentre/logging"
	"fmt"
	"time"

	"gorm.io/gorm"
)

type User struct {
	gorm.Model
	Email       string `gorm:"type:varchar(255);uniqueIndex;not null"`
	Role        RoleLevel
	DisplayName string `gorm:"type:varchar(128);default:'用户'"`
}

type RoleLevel int

const (
	Tourist RoleLevel = iota
	Publisher
	Admin
)

func init() {
	if err := database.DB.AutoMigrate(&User{}); err != nil {
		logging.Log.Fatalf("Mysql初始化User表失败: %s\n", err.Error())
	}
	logging.Log.Info("Mysql初始化User表完成.")
}

func GetUser(email string) (*User, error) {
	// 获取第一个email为指定email的用户
	var user User
	if err := database.DB.First(&user, "email = ?", email).Error; err != nil {
		return nil, err
	}
	return &user, nil
}

func GetAllPublishers() ([]User, error) {
	var users []User

	if err := database.DB.Find(&users, "role = ?", Publisher).Error; err != nil {
		return users, err
	}
	return users, nil
}

func GetAllUsers() ([]User, error) {
	var users []User

	if err := database.DB.Order("id desc").Find(&users).Error; err != nil {
		return users, err
	}
	return users, nil
}

func AddUser(user *User) int {
	// 检查该用户是否已经存在
	var tmp User
	if err := database.DB.First(&tmp, "email = ?", user.Email).Error; err == nil {
		logging.Log.Errorf("该用户(%s)已存在，不可重复创建.", user.Email)
		return -1
	} else { // 如果该用户不存在，则创建
		if err := database.DB.Create(user).Error; err != nil {
			logging.Log.Errorf("Create user failed: %s", err.Error())
			return -2
		}
	}
	return 0 // 成功创建
}

func UpdateUser(user *User) bool {
	if err := database.DB.Save(user).Error; err != nil {
		logging.Log.Errorf("更新用户信息失败: %s", err.Error())
		return false
	}
	return true
}

func UpdateDisplayName(user *User, displayName string) bool {
	if user.DisplayName == displayName {
		return true
	}
	if err := database.DB.Model(&user).Update("display_name", displayName).Error; err != nil {
		logging.Log.Errorf("更新用户显示名称失败: %s", err.Error())
		return false
	}
	return true
}

func AddAdministrator(email, displayName string) *User {
	if displayName == "" {
		displayName = getDisplayName()
	}
	user := User{
		Email:       email,
		Role:        Admin,
		DisplayName: displayName,
	}

	// add user to database
	if AddUser(&user) == 0 {
		return &user
	}
	return nil
}

func AddPublisher(email, displayName string) *User {
	if displayName == "" {
		displayName = getDisplayName()
	}
	user := User{
		Email:       email,
		Role:        Publisher,
		DisplayName: displayName,
	}

	// add user to database
	if AddUser(&user) == 0 {
		return &user
	}
	return nil
}

func DeleteUser(email string) error {
	if err := database.DB.Delete(&User{}, "email = ?", email).Error; err != nil {
		return err
	}
	return nil
}

func getDisplayName() string {
	return fmt.Sprintf("用户%v", time.Now().UnixNano()/1e6)
}
