<?php
namespace Misuzu\Forum;

use Index\DateTime;
use Index\Data\IDbResult;
use Index\Net\IPAddress;
use Misuzu\Parsers\Parser;

class ForumPostInfo {
    private string $id;
    private string $topicId;
    private string $categoryId;
    private ?string $userId;
    private string $remoteAddr;
    private string $body;
    private int $parser;
    private bool $displaySignature;
    private int $created;
    private ?int $edited;
    private ?int $deleted;

    public function __construct(IDbResult $result) {
        $this->id = (string)$result->getInteger(0);
        $this->topicId = (string)$result->getInteger(1);
        $this->categoryId = (string)$result->getInteger(2);
        $this->userId = $result->isNull(3) ? null : (string)$result->getInteger(3);
        $this->remoteAddr = $result->getString(4);
        $this->body = $result->getString(5);
        $this->parser = $result->getInteger(6);
        $this->displaySignature = $result->getInteger(7) !== 0;
        $this->created = $result->getInteger(8);
        $this->edited = $result->isNull(9) ? null : $result->getInteger(9);
        $this->deleted = $result->isNull(10) ? null : $result->getInteger(10);
    }

    public function getId(): string {
        return $this->id;
    }

    public function getTopicId(): string {
        return $this->topicId;
    }

    public function getCategoryId(): string {
        return $this->categoryId;
    }

    public function hasUserId(): bool {
        return $this->userId !== null;
    }

    public function getUserId(): ?string {
        return $this->userId;
    }

    public function getRemoteAddressRaw(): string {
        return $this->remoteAddr;
    }

    public function getRemoteAddress(): IPAddress {
        return IPAddress::parse($this->remoteAddr);
    }

    public function getBody(): string {
        return $this->body;
    }

    public function getParser(): int {
        return $this->parser;
    }

    public function isBodyPlain(): bool {
        return $this->parser === Parser::PLAIN;
    }

    public function isBodyBBCode(): bool {
        return $this->parser === Parser::BBCODE;
    }

    public function isBodyMarkdown(): bool {
        return $this->parser === Parser::MARKDOWN;
    }

    public function shouldDisplaySignature(): bool {
        return $this->displaySignature;
    }

    public function getCreatedTime(): int {
        return $this->created;
    }

    public function getCreatedAt(): DateTime {
        return DateTime::fromUnixTimeSeconds($this->created);
    }

    private static ?DateTime $markAsEditedThreshold = null;
    public function shouldMarkAsEdited(): bool {
        if(self::$markAsEditedThreshold === null)
            self::$markAsEditedThreshold = DateTime::now()->modify('-5 minutes');

        return $this->getCreatedAt()->isLessThan(self::$markAsEditedThreshold);
    }

    public function isEdited(): bool {
        return $this->edited !== null;
    }

    public function getEditedTime(): ?int {
        return $this->edited;
    }

    public function getEditedAt(): ?DateTime {
        return $this->edited === null ? null : DateTime::fromUnixTimeSeconds($this->edited);
    }

    private static ?DateTime $canBeDeletedThreshold = null;
    public function canBeDeleted(): bool {
        if(self::$canBeDeletedThreshold === null)
            self::$canBeDeletedThreshold = DateTime::now()->modify('-1 week');

        return $this->getCreatedAt()->isMoreThanOrEqual(self::$canBeDeletedThreshold);
    }

    public function isDeleted(): bool {
        return $this->deleted !== null;
    }

    public function getDeletedTime(): ?int {
        return $this->deleted;
    }

    public function getDeletedAt(): ?DateTime {
        return $this->deleted === null ? null : DateTime::fromUnixTimeSeconds($this->deleted);
    }
}
