<?php
namespace Misuzu\Forum;

use RuntimeException;
use Index\Data\DbStatementCache;
use Index\Data\IDbConnection;
use Misuzu\Pagination;
use Misuzu\Users\UserInfo;

class ForumTopicRedirects {
    private DbStatementCache $cache;

    public function __construct(IDbConnection $dbConn) {
        $this->cache = new DbStatementCache($dbConn);
    }

    public function countTopicRedirects(
        UserInfo|string|null $userInfo = null
    ): int {
        if($userInfo instanceof UserInfo)
            $userInfo = $userInfo->getId();

        $hasUserInfo = $userInfo !== null;

        $query = 'SELECT COUNT(*) FROM msz_forum_topics_redirects';
        if($hasUserInfo)
            $query .= ' WHERE user_id = ?';

        $stmt = $this->cache->get($query);
        if($hasUserInfo)
            $stmt->addParameter(1, $userInfo);
        $stmt->execute();

        $result = $stmt->getResult();
        return $result->next() ? $result->getInteger(0) : 0;
    }

    public function getTopicRedirects(
        UserInfo|string|null $userInfo = null,
        ?Pagination $pagination = null
    ): array {
        if($userInfo instanceof UserInfo)
            $userInfo = $userInfo->getId();

        $hasUserInfo = $userInfo !== null;
        $hasPagination = $pagination !== null;

        $query = 'SELECT topic_id, user_id, topic_redir_url, UNIX_TIMESTAMP(topic_redir_created) FROM msz_forum_topics_redirects';
        if($hasUserInfo)
            $query .= ' WHERE user_id = ?';
        if($hasPagination)
            $query .= ' LIMIT ? OFFSET ?';

        $args = 0;
        $stmt = $this->cache->get($query);
        if($hasUserInfo)
            $stmt->addParameter(++$args, $userInfo);
        if($hasPagination) {
            $stmt->addParameter(++$args, $pagination->getRange());
            $stmt->addParameter(++$args, $pagination->getOffset());
        }
        $stmt->execute();

        $result = $stmt->getResult();
        $redirs = [];

        while($result->next())
            $redirs[] = new ForumTopicRedirectInfo($result);

        return $redirs;
    }

    public function hasTopicRedirect(ForumTopicInfo|string $topicInfo): bool {
        if($topicInfo instanceof ForumTopicInfo)
            $topicInfo = $topicInfo->getId();

        $stmt = $this->cache->get('SELECT COUNT(*) FROM msz_forum_topics_redirects WHERE topic_id = ?');
        $stmt->addParameter(1, $topicInfo);
        $stmt->execute();

        $result = $stmt->getResult();
        if(!$result->next())
            throw new RuntimeException('Was unable to check if a redirect exists.');

        return $result->getInteger(0) > 0;
    }

    public function getTopicRedirect(ForumTopicInfo|string $topicInfo): ForumTopicRedirectInfo {
        if($topicInfo instanceof ForumTopicInfo)
            $topicInfo = $topicInfo->getId();

        $stmt = $this->cache->get('SELECT topic_id, user_id, topic_redir_url, UNIX_TIMESTAMP(topic_redir_created) FROM msz_forum_topics_redirects WHERE topic_id = ?');
        $stmt->addParameter(1, $topicInfo);
        $stmt->execute();

        $result = $stmt->getResult();
        if(!$result->next())
            throw new RuntimeException('Could not find that forum topic redirect.');

        return new ForumTopicRedirectInfo($result);
    }

    public function createTopicRedirect(
        ForumTopicInfo|string $topicInfo,
        UserInfo|string|null $userInfo,
        string $linkTarget
    ): ForumTopicRedirectInfo {
        if($topicInfo instanceof ForumTopicInfo)
            $topicInfo = $topicInfo->getId();
        if($userInfo instanceof UserInfo)
            $userInfo = $userInfo->getId();

        $stmt = $this->cache->get('INSERT INTO msz_forum_topics_redirects (topic_id, user_id, topic_redir_url) VALUES (?, ?, ?)');
        $stmt->addParameter(1, $topicInfo);
        $stmt->addParameter(2, $userInfo);
        $stmt->addParameter(3, $linkTarget);
        $stmt->execute();

        return $this->getTopicRedirect($topicInfo);
    }

    public function deleteTopicRedirect(ForumTopicRedirectInfo|ForumTopicInfo|string $topicInfo): void {
        if($topicInfo instanceof ForumTopicRedirectInfo)
            $topicInfo = $topicInfo->getTopicId();
        elseif($topicInfo instanceof ForumTopicInfo)
            $topicInfo = $topicInfo->getId();

        $stmt = $this->cache->get('DELETE FROM msz_forum_topics_redirects WHERE topic_id = ?');
        $stmt->addParameter(1, $topicInfo);
        $stmt->execute();
    }
}
