<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Entity;

use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\ORM\Event\PrePersistEventArgs;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity]
#[ORM\HasLifecycleCallbacks]
#[ORM\Table('chill_main_notification_comment')]
class NotificationComment implements TrackCreationInterface, TrackUpdateInterface
{
    #[Assert\NotBlank(message: 'notification.Comment content might not be blank')]
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT)]
    private string $content = '';

    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_IMMUTABLE, nullable: true)]
    private ?\DateTimeImmutable $createdAt = null;

    #[ORM\ManyToOne(targetEntity: User::class)]
    #[ORM\JoinColumn(nullable: true)]
    private ?User $createdBy = null;

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
    private ?int $id = null;

    #[ORM\ManyToOne(targetEntity: Notification::class, inversedBy: 'comments')]
    #[ORM\JoinColumn(nullable: false)]
    private ?Notification $notification = null;

    /**
     * Internal variable which detect if the comment is just persisted.
     *
     * @internal
     */
    private bool $recentlyPersisted = false;

    /**
     * TODO typo in property (hotfixed).
     */
    #[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_IMMUTABLE, nullable: true)]
    private ?\DateTimeImmutable $updateAt = null;

    #[ORM\ManyToOne(targetEntity: User::class)]
    #[ORM\JoinColumn(nullable: true)]
    private ?User $updatedBy = null;

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

    public function getCreatedAt(): ?\DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function getCreatedBy(): ?User
    {
        return $this->createdBy;
    }

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

    public function getNotification(): ?Notification
    {
        return $this->notification;
    }

    public function getUpdatedAt(): ?\DateTimeImmutable
    {
        return $this->updateAt;
    }

    public function getUpdatedBy(): ?User
    {
        return $this->updatedBy;
    }

    #[ORM\PreFlush]
    public function onFlushMarkNotificationAsUnread(PreFlushEventArgs $eventArgs): void
    {
        if ($this->recentlyPersisted) {
            foreach ($this->getNotification()->getAddressees() as $addressee) {
                if ($this->getCreatedBy() !== $addressee) {
                    $this->getNotification()->markAsUnreadBy($addressee);
                }
            }

            if ($this->getNotification()->getSender() !== $this->getCreatedBy()) {
                $this->getNotification()->markAsUnreadBy($this->getNotification()->getSender());
            }
        }
    }

    #[ORM\PrePersist]
    public function onPrePersist(PrePersistEventArgs $eventArgs): void
    {
        $this->recentlyPersisted = true;
    }

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

        return $this;
    }

    public function setCreatedAt(\DateTimeInterface $datetime): self
    {
        $this->createdAt = $datetime;

        return $this;
    }

    public function setCreatedBy(User $user): self
    {
        $this->createdBy = $user;

        return $this;
    }

    /**
     * @internal use Notification::addComment
     */
    public function setNotification(?Notification $notification): self
    {
        $this->notification = $notification;

        return $this;
    }

    /**
     * @deprecated use @see{self::setUpdatedAt} instead
     */
    public function setUpdateAt(?\DateTimeImmutable $updateAt): self
    {
        return $this->setUpdatedAt($updateAt);
    }

    public function setUpdatedAt(\DateTimeInterface $datetime): self
    {
        $this->updateAt = $datetime;

        return $this;
    }

    public function setUpdatedBy(User $user): self
    {
        $this->updatedBy = $user;

        return $this;
    }
}
