package common

import (
	"crypto/sha256"
	"errors"
	"time"

	"party.at/party/internal/data"
)

func (app *Application) LoginUser(email, password string) (*data.Token, error) {
	user, err := app.Models.Users.GetByEmail(email)
	if err != nil {
		if errors.Is(err, data.ErrRecordNotFound) {
			return nil, data.ErrInvalidCredentials
		}
		return nil, err
	}

	identities, err := app.Models.UserIdentities.GetByUser(user.ID)
	if err != nil {
		return nil, err
	}

	var authenticatedIdentity *data.UserIdentity
	for _, identity := range identities {
		match, err := identity.Password.Matches(password)
		if err != nil {
			return nil, err
		}
		if match {
			authenticatedIdentity = identity
			break
		}
	}

	if authenticatedIdentity == nil {
		return nil, data.ErrInvalidCredentials
	}

	return app.Models.Tokens.New(user.ID, authenticatedIdentity.ID, 24*time.Hour, data.ScopeAuthentication)
}

func (app *Application) GetUserFromToken(plaintext string) (*data.User, error) {
	userIdentity, err := app.Models.UserIdentities.GetForToken(data.ScopeAuthentication, plaintext)
	if err != nil {
		return nil, err
	}
	return app.Models.Users.Get(userIdentity.UserID)
}

func (app *Application) DeleteToken(plaintext string) error {
	hash := sha256.Sum256([]byte(plaintext))
	return app.Models.Tokens.Delete(hash[:])
}
