<?php

namespace App\Model;

use Nette\Database\Explorer;
use Nette\Database\SqlLiteral;
use Nette\Database\Table\Selection;
use Nette\Security\AuthenticationException;
use Nette\Security\Authenticator;
use Nette\Security\Passwords;
use Nette\Security\SimpleIdentity;

class AuthenticatorManager extends BaseManager implements Authenticator
{
    private Passwords $passwords;

    public function __construct(Explorer $database, Passwords $passwords)
    {
        parent::__construct($database);
        $this->passwords = $passwords;
    }

    function authenticate(string $username, string $password): SimpleIdentity
    {
        $user = $this->database->table('users')
            ->where('username', $username)
            ->where('deleted_at', null)
            ->fetch();

        if (!$user)
        {
            throw new AuthenticationException('UserNotFound.');
        }

        if (!$this->passwords->verify($password, $user->password)) {
            throw new AuthenticationException('InvalidPassword.');
        }

        $this->passwords->hash($password);
        return new SimpleIdentity(
            $user->id,
            $user->role,
            [
                'username' => $user->username,
                'email' => $user->email,
                'school_type' => $user->school_type,
                'profile_image' => $user->profile_image,
                'bio' => $user->bio,
            ]
        );
    }

    public function createUser($data)
    {
        $exists = $this->database->table('users')
                ->where('username', $data['username'])
                ->count('*') > 0;

        if ($exists) {
            return false;
        }

        return $this->database->table('users')
            ->insert([
                'username' => $data['username'],
                'role' => 'ucitel',
                'email' => $data['email'],
                'bio' => $data['bio'],
                'password' => $this->passwords->hash($data['password']),
                'school_type' => $data['school_type'],
                'created_at' => new SqlLiteral('NOW()'),
                'updated_at' => new SqlLiteral('NOW()'),
            ])->id;
    }

    public function getUser($id): Selection
    {
        return $this->database->table('users')->where('id', $id);
    }

    public function changePassword($userId, $newPassword): void
    {
        $this->getUser($userId)
            ->where('id', $userId)
            ->update([
                'password' => $this->passwords->hash($newPassword)
            ]);
    }
}