<?php

namespace App\Entity\Blog;

use App\Core\Doctrine\Timestampable;
use App\Core\Entity\EntityInterface;
use App\Core\File\FileAttribute;
use App\Repository\Blog\PostRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=PostRepository::class)
 * @ORM\Table(indexes={
 *    @ORM\Index(name="post_title", columns={"title"}, flags={"fulltext"}),
 *    @ORM\Index(name="post_content", columns={"content"}, flags={"fulltext"})
 * })
 * @ORM\HasLifecycleCallbacks
 */
class Post implements EntityInterface
{
    use Timestampable;

    const DRAFT = 0;
    const PUBLISHED = 1;

    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $title;

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private $content;

    /**
     * @ORM\Column(type="integer")
     */
    private $status;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $slug;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $publishedAt;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $image;

    /**
     * @ORM\ManyToMany(targetEntity=Category::class, inversedBy="posts")
     */
    private $categories;

    /**
     * @ORM\Column(type="string", length=20)
     */
    private $contentFormat;

    /**
     * @ORM\Column(type="array", nullable=true)
     */
    private $tags = [];

    /**
     * @ORM\Column(type="boolean", options={"default"=0})
     */
    private $isQuick = false;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $quickUrl;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $quickImage;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $quickVideo;

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    private $quickVideoWidth;

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    private $quickVideoHeight;

    /**
     * @ORM\Column(type="boolean", options={"default"=0})
     */
    private $quickShowVideo = false;

    /**
     * @ORM\OneToMany(targetEntity=Comment::class, mappedBy="post", orphanRemoval=true)
     */
    private $comments;

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private $notebook;

    /**
     * @ORM\OneToMany(targetEntity=PostFollow::class, mappedBy="post", orphanRemoval=true)
     */
    private $postFollows;

    public function __construct()
    {
        $this->categories = new ArrayCollection();
        $this->comments = new ArrayCollection();
        $this->postFollows = new ArrayCollection();
    }

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

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

    public function setTitle(?string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function getContent(): ?string
    {
        if ('editorjs' === $this->getContentFormat()) {
            return $this->content ?? '[]';
        }

        return $this->content;
    }

    public function setContent(?string $content): self
    {
        $this->content = $content;

        return $this;
    }

    public function getStatus(): ?int
    {
        return $this->status;
    }

    public function setStatus(int $status): self
    {
        $this->status = $status;

        return $this;
    }

    public function getImage()
    {
        return FileAttribute::handleFile($this->image);
    }

    public function setImage(?string $image, bool $force = false): self
    {
        if (false === $force && null === $image) {
            return $this;
        }

        $this->image = $image;

        return $this;
    }

    public function getSlug(): ?string
    {
        return $this->slug;
    }

    public function setSlug(?string $slug): self
    {
        $this->slug = $slug;

        return $this;
    }

    public function getPublishedAt(): ?\DateTimeInterface
    {
        return $this->publishedAt;
    }

    public function setPublishedAt(?\DateTimeInterface $publishedAt): self
    {
        $this->publishedAt = $publishedAt;

        return $this;
    }

    public function getImageCaption(): ?string
    {
        return $this->imageCaption;
    }

    public function setImageCaption(?string $imageCaption): self
    {
        $this->imageCaption = $imageCaption;

        return $this;
    }

    /**
     * @return Collection|Category[]
     */
    public function getCategories(): Collection
    {
        return $this->categories;
    }

    public function addCategory(Category $category): self
    {
        if (!$this->categories->contains($category)) {
            $this->categories[] = $category;
        }

        return $this;
    }

    public function removeCategory(Category $category): self
    {
        $this->categories->removeElement($category);

        return $this;
    }

    public function getContentFormat(): ?string
    {
        return $this->contentFormat;
    }

    public function setContentFormat(string $contentFormat): self
    {
        $this->contentFormat = $contentFormat;

        return $this;
    }

    public function getTags(): ?array
    {
        $tags = [];

        foreach ($this->tags as $tag) {
            if (is_string($tag)) {
                $tags[] = ['label' => $tag];
            } else {
                $tags[] = $tag;
            }
        }

        usort($tags, function ($a, $b) {
            return $a['label'] < $b['label'] ? -1 : 1;
        });

        return $tags;
    }

    public function setTags(?array $tags): self
    {
        $this->tags = $tags;

        return $this;
    }

    public function getIsQuick(): ?bool
    {
        return $this->isQuick;
    }

    public function setIsQuick(bool $isQuick): self
    {
        $this->isQuick = $isQuick;

        return $this;
    }

    public function getQuickUrl(): ?string
    {
        return $this->quickUrl;
    }

    public function setQuickUrl(?string $quickUrl): self
    {
        $this->quickUrl = $quickUrl;

        return $this;
    }

    public function getQuickImage(): ?string
    {
        return $this->quickImage;
    }

    public function setQuickImage(?string $quickImage): self
    {
        $this->quickImage = $quickImage;

        return $this;
    }

    public function getQuickVideo(): ?string
    {
        return $this->quickVideo;
    }

    public function setQuickVideo(?string $quickVideo): self
    {
        $this->quickVideo = $quickVideo;

        return $this;
    }

    public function getQuickVideoWidth(): ?int
    {
        return $this->quickVideoWidth;
    }

    public function setQuickVideoWidth(?int $quickVideoWidth): self
    {
        $this->quickVideoWidth = $quickVideoWidth;

        return $this;
    }

    public function getQuickVideoHeight(): ?int
    {
        return $this->quickVideoHeight;
    }

    public function setQuickVideoHeight(?int $quickVideoHeight): self
    {
        $this->quickVideoHeight = $quickVideoHeight;

        return $this;
    }

    /**
     * @return Collection|Comment[]
     */
    public function getComments(array $criteria = []): Collection
    {
        $collection = new ArrayCollection();

        foreach ($this->comments as $comment) {
            if (isset($criteria['isActive']) && $comment->getIsActive() !== $criteria['isActive']) {
                continue;
            }

            if (isset($criteria['isFirstLevel']) && $criteria['isFirstLevel'] !== (null === $comment->getParentComment())) {
                continue;
            }

            if (isset($criteria['id']) && $comment->getId() !== $criteria['id']) {
                continue;
            }

            $collection->add($comment);
        }

        return $collection;
    }

    public function addComment(Comment $comment): self
    {
        if (!$this->comments->contains($comment)) {
            $this->comments[] = $comment;
            $comment->setPost($this);
        }

        return $this;
    }

    public function removeComment(Comment $comment): self
    {
        if ($this->comments->removeElement($comment)) {
            // set the owning side to null (unless already changed)
            if ($comment->getPost() === $this) {
                $comment->setPost(null);
            }
        }

        return $this;
    }

    public function getNotebook(): ?string
    {
        return $this->notebook;
    }

    public function setNotebook(?string $notebook): self
    {
        $this->notebook = $notebook;

        return $this;
    }

    /**
     * @return Collection|PostFollow[]
     */
    public function getPostFollows(): Collection
    {
        return $this->postFollows;
    }

    public function addPostFollow(PostFollow $postFollow): self
    {
        if (!$this->postFollows->contains($postFollow)) {
            $this->postFollows[] = $postFollow;
            $postFollow->setPost($this);
        }

        return $this;
    }

    public function removePostFollow(PostFollow $postFollow): self
    {
        if ($this->postFollows->removeElement($postFollow)) {
            // set the owning side to null (unless already changed)
            if ($postFollow->getPost() === $this) {
                $postFollow->setPost(null);
            }
        }

        return $this;
    }

    public function getQuickShowVideo(): ?bool
    {
        return $this->quickShowVideo;
    }

    public function setQuickShowVideo(bool $quickShowVideo): self
    {
        $this->quickShowVideo = $quickShowVideo;

        return $this;
    }
}
