<?php

namespace App\Entity\Blog;

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

/**
 * @ORM\Entity(repositoryClass=CommentRepository::class)
 * @ORM\HasLifecycleCallbacks
 */
class Comment implements EntityInterface
{
    use Timestampable;

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

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

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

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

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

    /**
     * @ORM\Column(type="boolean")
     */
    private $isActive;

    /**
     * @ORM\ManyToOne(targetEntity=Post::class, inversedBy="comments")
     * @ORM\JoinColumn(nullable=false)
     */
    private $post;

    /**
     * @ORM\ManyToOne(targetEntity=Comment::class, inversedBy="comments")
     * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
     */
    private $parentComment;

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

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

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

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

    public function getAuthor(): ?string
    {
        return $this->author;
    }

    public function setAuthor(string $author): self
    {
        $this->author = $author;

        return $this;
    }

    public function getWebsite(): ?string
    {
        return $this->website;
    }

    public function setWebsite(?string $website): self
    {
        $this->website = $website;

        return $this;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(?string $email): self
    {
        $this->email = $email;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

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

        return $this;
    }

    public function getIsActive(): ?bool
    {
        return $this->isActive;
    }

    public function setIsActive(bool $isActive): self
    {
        $this->isActive = $isActive;

        return $this;
    }

    public function getPost(): ?Post
    {
        return $this->post;
    }

    public function setPost(?Post $post): self
    {
        $this->post = $post;

        return $this;
    }

    public function getParentComment(): ?self
    {
        return $this->parentComment;
    }

    public function setParentComment(?self $parentComment): self
    {
        $this->parentComment = $parentComment;

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

            $collection->add($comment);
        }

        return $collection;
    }

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

        return $this;
    }

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

        return $this;
    }

    /**
     * Get the avatar URL using gravatar.
     */
    public function getAvatar(): string
    {
        $mail = $this->getEmail() ?? sprintf('%d@deblan.io', $this->getId());
        $hash = md5($mail);

        return 'https://cdn.libravatar.org/avatar/'.$hash.'?s=90&d=retro';
    }

    /**
     * {@inheritdoc}
     */
    public function __toString()
    {
        return sprintf(
            '[%s] (%s) %s',
            $this->getAuthor(),
            $this->getCreatedAt()->format('d/m/Y'),
            substr($this->getContent(), 0, 20).'…'
        );
    }

    /**
     * @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->setComment($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->getComment() === $this) {
                $postFollow->setComment(null);
            }
        }

        return $this;
    }
}
