<?php declare(strict_types=1);
namespace App\Repository;

error_reporting(error_level: E_ALL);

use App\Controller\DatabaseConnection;
use App\Controller\EncryptionController;
use App\Entity\Apikey;
use PDO;
use PDOException;

/**
 *
 */
class ApikeyRepository
{
	public function __construct(private readonly DatabaseConnection $databaseConnection, EncryptionController $encryptionController)
	{}
	
	
	/**
	 * @return array|false
	 */
	public function findAll(): bool|array
	{

		$sql = "
            SELECT id, name, apikey_prefix, apikey
            FROM " . DatabaseConnection::TABLE_APIKEYS;
		
		try {
			$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
			$statement->execute();
			
			$apikeys = [];
			
			while ($result = $statement->fetch()) {
				$apikey = new Apikey(id: $result['id'], name: $result['name'], apikey: $result['apikey'], apikeyPrefix: $result['apikey_prefix']);
				$apikeys[] = $apikey;
			}
			return $apikeys;
		} catch (PDOException $e) {
			exit($e->getMessage());
		}
	}
	
	
	/**
	 * @param Int $id
	 *
	 * @return Apikey|bool
	 */
	public function findByID(Int $id): Apikey|bool
	{
		$sql = "
			SELECT id, name, apikey_prefix, apikey
			FROM " . DatabaseConnection::TABLE_APIKEYS . "
            WHERE id = :id;
        ";
		
		try {
			$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
			$statement->bindParam(param: ':id', var: $id);
			$statement->execute();
			if ($result = $statement->fetch(mode: PDO::FETCH_ASSOC)) {
				return new Apikey(id: $result['id'], name: $result['name'], apikey: $result['apikey'], apikeyPrefix: $result['apikey_prefix']);
			} else {
				return false;
			}
		} catch (PDOException $e) {
			exit($e->getMessage());
		}
	}
	
	
	/**
	 * @param String $prefix
	 *
	 * @return Apikey|bool
	 */
	public function findByPrefix(String $prefix): Apikey|bool
	{
		$sql = "
			SELECT id, name, apikey_prefix, apikey
			FROM " . DatabaseConnection::TABLE_APIKEYS . "
            WHERE apikey_prefix = :prefix";
		
		try {
			$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
			$statement->bindParam(param: ':prefix', var: $prefix);
			$statement->execute();
			if ($result =  $statement->fetch(mode: PDO::FETCH_ASSOC)) {
				return new Apikey(id: $result['id'], name: $result['name'], apikey: $result['apikey'], apikeyPrefix: $result['apikey_prefix']);
			} else {
				return false;
			}
		} catch (PDOException $e) {
			exit($e->getMessage());
		}
	}


    /**
     * @param Apikey $apikey
     * @return int
     */
	public function insert(ApiKey $apikey): int
    {

        $name = $apikey->getName();
        $apikeyPrefix = $apikey->getApikeyPrefix();
        $apikeyValue = $apikey->getApikey();

		$sql = "
            INSERT INTO " . DatabaseConnection::TABLE_APIKEYS . " (name, apikey_prefix, apikey)
            VALUES (:name, :apikey_prefix, :apikey)";
		
		try {
			$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
            $statement->bindParam(param: ':name', var: $name);
			$statement->bindParam(param: ':apikey_prefix', var: $apikeyPrefix);
			$statement->bindParam(param: ':apikey', var: $apikeyValue);

			$statement->execute();
			return intval(value: $this->databaseConnection->getConnection()->lastInsertId());
		} catch (PDOException $e) {
			exit($e->getMessage());
		}
	}

    /**
     * @param Apikey $apikey
     * @return false|int
     */
	public function update(Apikey $apikey): bool|int
	{
        $id = $apikey->getId();
        $name = $apikey->getName();

        $current = $this->findByID(id: $id);

        if (empty($name)) {
            $name = $current->getName();
        }

		$sql = "
			UPDATE " . DatabaseConnection::TABLE_APIKEYS . " SET
				name = :name
            WHERE id = :id";
		
		try {
			$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
			$statement->bindParam(param: 'id', var: $id);
			$statement->bindParam(param: 'name', var: $name);
			$statement->execute();
			
			return $statement->rowCount();
		} catch (PDOException $e) {
			echo $e->getMessage();
			return false;
		}
	}
	
	
	/**
	 * @param $id
	 *
	 * @return int
	 */
	public function delete($id): int
	{
		$sql = "
            DELETE FROM " . DatabaseConnection::TABLE_APIKEYS . "
            WHERE id = :id";
		
		try {
			$statement = $this->databaseConnection->getConnection()->prepare(query: $sql);
			$statement->bindParam(param: 'id', var: $id);
			$statement->execute();
			return $statement->rowCount();
		} catch (PDOException $e) {
			exit($e->getMessage());
		}
	}
	
}
