package storage

import (
	"errors"
	"status/model"
)

const queryFindName = `SELECT name, hash, created_at, homepage, about, picture, email, active, signup_email FROM users WHERE name=lower($1);`

func (s *Storage) queryUser(q string, params ...interface{}) (user model.User, err error) {
	err = s.db.QueryRow(q, params...).Scan(&user.Name, &user.Hash, &user.CreatedAt, &user.Homepage, &user.About, &user.Picture, &user.Email, &user.Active, &user.SignupEmail)
	return
}
func (s *Storage) ActivateAllUsers() error {
    _, err := s.db.Exec(`UPDATE users SET active = true;`)
    return err
}
func (s *Storage) VerifyUser(user model.User) (model.User, error) {
	u, err := s.queryUser(queryFindName, user.Name)
	if err != nil {
		return u, err
	}
	if err := user.CompareHashToPassword(u.Hash); err != nil {
		return u, errors.New("incorrect password")
	}
	if !u.Active {
		return u, errors.New("user not active")
	}
	return u, nil
}

func (s *Storage) UserExists(name string) bool {
	var rv bool
	s.db.QueryRow(`SELECT true FROM users WHERE name=lower($1)`, name).Scan(&rv)
	return rv
}

func (s *Storage) UserByName(name string) (model.User, error) {
	return s.queryUser(queryFindName, name)
}

func (s *Storage) CreateUser(user model.User) error {
	hash, err := user.HashPassword()
	if err != nil {
		return err
	}
	insertUser := `INSERT INTO users (name, hash, email, signup_email, signup_msg, active) VALUES (lower($1), $2, $3, $4, $5, $6)`
	statement, err := s.db.Prepare(insertUser)
	if err != nil {
		return err
	}
	_, err = statement.Exec(user.Name, hash, user.Email, user.SignupEmail, user.SignupMsg, user.Active)
	return err
}

func (s *Storage) Users() ([]string, error) {
	rows, err := s.db.Query("select name from users")
	if err != nil {
		return nil, err
	}
	var users []string
	for rows.Next() {
		var user string
		err := rows.Scan(&user)
		if err != nil {
			return users, err
		}
		users = append(users, user)
	}
	return users, nil
}

func (s *Storage) InactiveUsers() ([]model.User, error) {
	rows, err := s.db.Query("select name, signup_email, signup_msg from users where active is false")
	if err != nil {
		return nil, err
	}
	var users []model.User
	for rows.Next() {
		var user model.User
		err := rows.Scan(&user.Name, &user.SignupEmail, &user.SignupMsg)
		if err != nil {
			return users, err
		}
		users = append(users, user)
	}
	return users, nil
}

func (s *Storage) ActivateUser(name string) error {
	stmt, err := s.db.Prepare(`UPDATE users SET active = true WHERE name = $1;`)
	if err != nil {
		return err
	}
	_, err = stmt.Exec(name)
	return err
}

func (s *Storage) DeleteUser(username string) error {
	stmt, err := s.db.Prepare(`DELETE from users WHERE name = $1;`)
	if err != nil {
		return err
	}
	_, err = stmt.Exec(username)
	return err
}

func (s *Storage) UpdateSettings(username, homepage, about, picture, email string) error {
	stmt, err := s.db.Prepare(`UPDATE users SET homepage = $1, about = $2, picture = $3, email = $4 WHERE name = $5;`)
	if err != nil {
		return err
	}
	_, err = stmt.Exec(homepage, about, picture, email, username)
	return err
}

