package user

import (
	"errors"
	"github.com/jmoiron/sqlx"
	"golang.org/x/crypto/bcrypt"
)

type User struct {
	Id int
	Username string
	Password string
	Name string
	AboutMe string `db:"aboutme"`
	Location string
	Webpage string
	Image string
}


func GetUserById(sqlx *sqlx.DB, id int) (User, error) {
	users := []User{}
	err := sqlx.Select(&users, "SELECT * FROM users WHERE id = ?", id)
	if err != nil {
		return User{}, nil
	}
	if len(users) == 0 {
		return User{}, errors.New("User not found")
	}
	if len(users) > 1 {
		return User{}, errors.New("User not unique")
	}

	return users[0], nil
}

func GetUserByUsername(sqlx *sqlx.DB, username string) (User, error) {
	users := []User{}
	err := sqlx.Select(&users, "SELECT * FROM users WHERE username = ?", username)
	if err != nil {
		return User{}, nil
	}
	if len(users) == 0 {
		return User{}, errors.New("User not found")
	}
	if len(users) > 1 {
		return User{}, errors.New("User not unique")
	}

	return users[0], nil
}

func CheckUsernameIsFree(sqlx *sqlx.DB, username string) (bool, error) {
	rows, err := sqlx.NamedQuery(`SELECT count(1) AS 'count' FROM users WHERE username=:username`, map[string]interface{}{"username": username})

	if err != nil {
		return false, err
	}

	checkUserResult := make(map[string]interface{})
	rows.Next()
	err = rows.MapScan(checkUserResult)
	if err != nil {
		return false, err
	}

	if checkUserResult["count"].(int64) > 0 {
		return false, nil
	}
	return true, nil
}

func Register(sqlx *sqlx.DB, username, password string) (int64, error) {
	hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.MinCost)
	hashstring := string(hash)

	res, err := sqlx.NamedExec(`INSERT INTO users (username,password) VALUES (:username,:password)`,
		map[string]interface{}{
			"username": username,
			"password": hashstring,
		})
	if err != nil {
		return 0, err
	}

	id, err := res.LastInsertId()
	if err != nil {
		return 0, err
	}

	return id, nil
}

func UpdateUser(sqlx *sqlx.DB, user User) (error) {
	_, err := sqlx.NamedExec("UPDATE users SET name = :name, aboutme = :aboutme, location = :location, webpage = :webpage, image = :image WHERE id = :id", user)
	return err
}