<?php

declare(strict_types=1);

namespace kodorvan\surikov\models;

// Built-in libraries
use pdo,
exception;


/**
 * Publication model
 *
 * @package kodorvan\surikov\models
 *
 * @param
 *
 * @method static int|null write(string $title, ?string $content, int $active, int $account, array &$errors) Write
 *
 * @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
 * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
 */
final class publication extends core
{
    /**
     * Write
     *
     * Write into the database
     *
     * @param string $title Title
     * @param string|null $content Сontent
     * @param int $active Active of the publication
     * @param int $account Identifier of the publication
     * @param array &$errors Registry of errors
     *
     * @return int|bool The book publication
     */
    public static function write(string $title, ?string $content, int $active, int $account, array &$errors = []): int|bool
    {
        try {
            //Current date
            $time = date("Y-m-d H:i:s");

            // Initializing the request
            $request = static::$database->prepare("INSERT INTO `publications` (`account`, `title`, `content`,  `updated`, `created`,`active`) VALUES (:account, :title, :content,  :updated, :created, :active) ;");

            // Initializing the request parameters
            $parameters = [
                ':account' => $account,
                ':title' => $title,
                ':content' => $content,
                ':updated' => $time,
                ':created' => $time,
                ':active' => $active
            ];

            // Sending the request
            $request->execute($parameters);

            // Initializing the request
            $request = static::$database->prepare("SELECT `identifier` FROM `publications` WHERE `account` = :account AND `created` = :created ORDER BY `identifier` DESC LIMIT 1");

            // Initializing the request parameters
            $request->execute([
                ':account' => $account,
                ':created' => $time
            ]);

            //Getting the identifier
            $result = $request->fetch(PDO::FETCH_ASSOC);

            //Exit (true)
            return (int) $result['identifier'];

        } catch (exception $e) {
            // Exception

            // Writing into the errors registry
            $errors[] = [
                'text' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'stack' => $e->getTrace()
            ];
        }

        // Exit (fail)
        return false;
    }

    /**
     * Read
     *
     * Read publication from the database
     *
     * @param array $expressions Request expressions
     * @param string $sort Sort
     * @param int $limit Amount
     * @param int $page Page (offset by $limit)
     * @param array &$errors Registry of errors
     *
     * @return array|false Books
     */
    public static function read(array $expressions = [], string $sort = '', int $limit = 1, int $page = 1, array &$errors = []): array|false
    {
        try {
            // Initializing the request row
            $row = 'WHERE ';

            // Initializing the request parameters
            $parameters = [];

            foreach ($expressions as $name => $value) {
                // Iterating over the request expressions

                // Generating the request row
                $row .= "`$name` = :$name &&";

                // Generating the request parameters
                $parameters[":$name"] = $value;
            }

            // Cleaning the request row
            $row = empty($expressions) ? '' : trim(trim($row, '&&'));

            //Forming a query sort
            $order = empty($sort) ? '' : "ORDER BY $sort";

            // Initializing the page
            $page = $limit * --$page;

            // Initializing the request
            $request = static::$database->prepare("SELECT * FROM `publications` $row $order LIMIT $page, $limit");

            // Sending the request
            $request->execute($parameters);

            // Exit (success)
            return (array) $request->fetchAll(pdo::FETCH_ASSOC);
        } catch (exception $e) {
            // Exception

            // Writing into the errors registry
            $errors[] = [
                'text' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'stack' => $e->getTrace()
            ];
        }

        // Exit (fail)
        return false;
    }

    /**
     * Update
     *
     * Update the database from the database
     *
     * @param int $identifier Identifier
     * @param string $title Title
     * @param string $content Content
     * 
     * @param array &$errors Registry of errors
     *
     * @return bool Is the publications was deleted?
     */
    public static function update(int $identifier, string $title, ?string $content, ?array $files, array &$errors = []): ?bool
    {
        try {
            // Initializing the request
            $request = static::$database->prepare("UPDATE `publications` SET `title` = :title, `content` = :content WHERE `identifier` = :identifier ");

            // Initializing the request parameters
            $parameters = [
                ':title' => $title,
                ':content' => $content,
                ':identifier' => $identifier,
            ];

            // Sending the request
            $request->execute($parameters);

            // Exit (success)
            return true;

        } catch (exception $e) {
            // Exception

            // Writing into the errors registry
            $errors[] = [
                'text' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'stack' => $e->getTrace()
            ];
        }

        // Exit (fail)
        return false;
    }

    /**
     * Delete
     *
     * Delete the publication from the database
     *
     * @param int $identifier Identifier
     * @param int $active Active
     * @param int $limit Amount
     * 
     * @param array &$errors Registry of errors
     *
     * @return bool Is the publication was deleted?
     */
    public static function delete(int $identifier, int $active, array &$errors = []): bool
    {
        try {
            // Initializing the request
            $request = static::$database->prepare("UPDATE `publications` SET `active` = :active WHERE `identifier` = :identifier LIMIT 1");

            // Initializing the request parameters
            $parameters = [
                ':identifier' => $identifier,
                ':active' => $active,
            ];

            // Sending the request
            $request->execute($parameters);

            // Exit (success)
            return true;

        } catch (exception $e) {
            // Exception

            // Writing into the errors registry
            $errors[] = [
                'text' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'stack' => $e->getTrace()
            ];
        }

        // Exit (fail)
        return false;
    }

}