<?php
namespace Misuzu\Forum;

use Index\DateTime;
use Index\Data\IDbResult;

class ForumTopicInfo {
    public const TYPE_DISCUSSION = 0;
    public const TYPE_STICKY = 1;
    public const TYPE_ANNOUNCE = 2;
    public const TYPE_GLOBAL = 3;

    public const TYPE_ALIASES = [
        'discussion' => self::TYPE_DISCUSSION,
        'sticky' => self::TYPE_STICKY,
        'announce' => self::TYPE_ANNOUNCE,
        'global' => self::TYPE_GLOBAL,
    ];

    private string $id;
    private string $categoryId;
    private ?string $userId;
    private int $type;
    private string $title;
    private int $postsCount;
    private int $deletedPostsCount;
    private int $viewsCount;
    private int $created;
    private int $bumped;
    private ?int $deleted;
    private ?int $locked;

    public function __construct(IDbResult $result) {
        $this->id = (string)$result->getInteger(0);
        $this->categoryId = (string)$result->getInteger(1);
        $this->userId = $result->isNull(2) ? null : (string)$result->getInteger(2);
        $this->type = $result->getInteger(3);
        $this->title = $result->getString(4);
        $this->viewsCount = $result->getInteger(5);
        $this->created = $result->getInteger(6);
        $this->bumped = $result->getInteger(7);
        $this->deleted = $result->isNull(8) ? null : $result->getInteger(8);
        $this->locked = $result->isNull(9) ? null : $result->getInteger(9);
        $this->postsCount = $result->getInteger(10);
        $this->deletedPostsCount = $result->getInteger(11);
    }

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

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

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

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

    public function getType(): int {
        return $this->type;
    }

    public function getTypeString(): string {
        return match($this->type) {
            self::TYPE_GLOBAL => 'global',
            self::TYPE_ANNOUNCE => 'announce',
            self::TYPE_STICKY => 'sticky',
            default => 'discussion',
        };
    }

    public function isDiscussion(): bool {
        return $this->type === self::TYPE_DISCUSSION;
    }

    public function isSticky(): bool {
        return $this->type === self::TYPE_STICKY;
    }

    public function isAnnouncement(): bool {
        return $this->type === self::TYPE_ANNOUNCE;
    }

    public function isGlobalAnnouncement(): bool {
        return $this->type === self::TYPE_GLOBAL;
    }

    public function isImportant(): bool {
        return $this->isSticky()
            || $this->isAnnouncement()
            || $this->isGlobalAnnouncement();
    }

    public function getIconForDisplay(bool $unread = false): string {
        if($this->isDeleted())
            return 'fas fa-trash-alt fa-fw';
        if($this->isAnnouncement() || $this->isGlobalAnnouncement())
            return 'fas fa-bullhorn fa-fw';
        if($this->isSticky())
            return 'fas fa-thumbtack fa-fw';
        if($this->isLocked())
            return 'fas fa-lock fa-fw';
        return sprintf('%s fa-comment fa-fw', $unread ? 'fas' : 'far');
    }

    public function getTitle(): string {
        return $this->title;
    }

    public function getPostsCount(): int {
        return $this->postsCount;
    }

    public function getDeletedPostsCount(): int {
        return $this->deletedPostsCount;
    }

    public function getTotalPostsCount(): int {
        return $this->postsCount + $this->deletedPostsCount;
    }

    public function getViewsCount(): int {
        return $this->viewsCount;
    }

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

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

    private static ?DateTime $lastActiveAt = null;

    public function isActive(): bool {
        if(self::$lastActiveAt === null)
            self::$lastActiveAt = DateTime::now()->modify('-1 month');

        return $this->getBumpedAt()->isMoreThanOrEqual(self::$lastActiveAt);
    }

    public function getBumpedTime(): int {
        return $this->bumped;
    }

    public function getBumpedAt(): DateTime {
        return DateTime::fromUnixTimeSeconds($this->bumped);
    }

    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);
    }

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

    public function getLockedTime(): ?int {
        return $this->locked;
    }

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