<?php
namespace Misuzu\Comments;

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

class CommentsPostInfo {
    public function __construct(
        private string $id,
        private string $categoryId,
        private ?string $userId,
        private ?string $replyingTo,
        private string $body,
        private int $created,
        private ?int $pinned,
        private ?int $updated,
        private ?int $deleted,
        private int $replies,
        private int $votesTotal,
        private int $votesPositive,
        private int $votesNegative,
    ) {}

    public static function fromResult(
        IDbResult $result,
        bool $includeRepliesCount = false,
        bool $includeVotesCount = false
    ): CommentsPostInfo {
        $args = [];
        $count = 0;

        $args[] = $result->getString($count); // id
        $args[] = $result->getString(++$count); // categoryId
        $args[] = $result->getStringOrNull(++$count); // userId
        $args[] = $result->getStringOrNull(++$count); // replyingTo
        $args[] = $result->getString(++$count); // body
        $args[] = $result->getInteger(++$count); // created
        $args[] = $result->getIntegerOrNull(++$count); // pinned
        $args[] = $result->getIntegerOrNull(++$count); // updated
        $args[] = $result->getIntegerOrNull(++$count); // deleted

        $args[] = $includeRepliesCount ? $result->getInteger(++$count) : 0;

        if($includeVotesCount) {
            $args[] = $result->getInteger(++$count); // votesTotal
            $args[] = $result->getInteger(++$count); // votesPositive
            $args[] = $result->getInteger(++$count); // votesNegative
        } else {
            $args[] = 0;
            $args[] = 0;
            $args[] = 0;
        }

        return new CommentsPostInfo(...$args);
    }

    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 isReply(): bool {
        return $this->replyingTo !== null;
    }

    public function getReplyingTo(): ?string {
        return $this->replyingTo;
    }

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

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

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

    public function getPinnedTime(): ?int {
        return $this->pinned;
    }

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

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

    public function getUpdatedTime(): ?int {
        return $this->updated;
    }

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

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

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

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

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

    public function hasRepliesCount(): bool {
        return $this->replies > 0;
    }

    public function getRepliesCount(): int {
        return $this->replies;
    }

    public function hasVotesCount(): bool {
        return $this->votesTotal > 0;
    }

    public function getVotesTotal(): int {
        return $this->votesTotal;
    }

    public function getVotesPositive(): int {
        return $this->votesPositive;
    }

    public function getVotesNegative(): int {
        return $this->votesNegative;
    }
}
