<?php

namespace objects;

use classes\db;
use classes\object_property;
use Exception;
use traits\db_object_t;

class tokens_o extends db
{
    use db_object_t;

    public object_property $user_id;
    public object_property $type; // AUTH_TOKEN, RESET_PASSWORD, AUTH_TOKEN_SUBUSER
    public object_property $token;

    public function structure(): void
    {
        $this->setTable('tokens');
    }

    public function objectChanged(): void
    {
        // Invalidate the cache
        redis->clear_token($this->token->value());
    }

    public function create(int $user_id, string $token, string $type = 'AUTH_TOKEN'): void
    {
        global $db;
        // Avoid SQL injection
        $token = $db->escape_string($token);
        // Create a new record in the database
        $sql = "INSERT INTO $this->table (user_id, token, type) VALUES ($user_id, '$token', '$type')";
        $db->query($sql);

        // Get the id of the new record
        $this->id = $db->insert_id();

        // Set the values of the object properties
        $this->getObjectProperties();
    }

    public function getObjectProperties(): void
    {
        $this->user_id = new object_property($this->table, $this->id, 'user_id', 'int', true);
        $this->type = new object_property($this->table, $this->id, 'type', 'string', true);
        $this->token = new object_property($this->table, $this->id, 'token', 'string', true);
    }

    /**
     * @throws Exception
     */
    public function getToken(string $token): tokens_o
    {
        global $db;
        // Check if the token is cached
        $cached = redis->get_token($token);
        if ($cached) {
            $this->id = $cached['id'];
            $this->getObjectProperties();
            return $this;
        }
        // Avoid SQL injection
        $token = $db->escape_string($token);
        // Prepare the SQL statement
        $sql = "SELECT id FROM $this->table WHERE token = '$token'";
        $result = $db->query($sql);
        $row = $db->fetch_assoc($result);
        if (!$row) {
            throw new Exception("Token not found " . $token);
        }
        // Cache the token
        redis->cache_token($token, $row);
        $this->id = $row['id'];
        $this->getObjectProperties();
        return $this;
    }

    public function delete(string $token): void
    {
        global $db;
        // Avoid SQL injection
        $token = $db->escape_string($token);
        // Prepare the SQL statement
        $sql = "DELETE FROM $this->table WHERE token = '$token'";
        $db->query($sql);

        // Clear the token from the cache
        redis->clear_token($token);
    }
}