<?php
namespace Misuzu\Forum;

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

class ForumPostInfo {
    public function __construct(
        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 static function fromResult(IDbResult $result): ForumPostInfo {
        return new ForumPostInfo(
            id: $result->getString(0),
            topicId: $result->getString(1),
            categoryId: $result->getString(2),
            userId: $result->getStringOrNull(3),
            remoteAddr: $result->getString(4),
            body: $result->getString(5),
            parser: $result->getInteger(6),
            displaySignature: $result->getBoolean(7),
            created: $result->getInteger(8),
            edited: $result->getIntegerOrNull(9),
            deleted: $result->getIntegerOrNull(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);
    }
}
