<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Ferienpass\CoreBundle\Repository\ActivityNotificationRepository;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;

/**
 * A per-recipient inbox row that drives the header notification bell. One row is
 * created for each admin colleague who should be alerted about a {@see ConversationItem}.
 */
#[ORM\Entity(repositoryClass: ActivityNotificationRepository::class)]
#[ORM\Index(columns: ['recipient_id', 'readAt'])]
#[ORM\Index(columns: ['recipient_id', 'createdAt'])]
class ActivityNotification
{
    /** Recipient was named in a direct @person mention. */
    public const REASON_MENTION = 'mention';
    /** Recipient is part of a notified group (e.g. @Admin-Team). */
    public const REASON_GROUP = 'group';
    /** A reply was posted in a thread the recipient takes part in. */
    public const REASON_REPLY = 'reply';

    #[ORM\Id]
    #[ORM\Column(type: UuidType::NAME)]
    private Uuid $uuid;

    #[ORM\ManyToOne(targetEntity: ConversationItem::class, inversedBy: 'notifications')]
    #[ORM\JoinColumn(name: 'conversation_item_id', referencedColumnName: 'uuid', onDelete: 'CASCADE')]
    private ConversationItem $conversationItem;

    #[ORM\ManyToOne(targetEntity: User::class)]
    #[ORM\JoinColumn(name: 'recipient_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
    private User $recipient;

    #[ORM\Column(type: 'string', length: 16)]
    private string $reason;

    #[ORM\Column(type: 'datetime_immutable', options: ['default' => 'CURRENT_TIMESTAMP'])]
    private \DateTimeInterface $createdAt;

    #[ORM\Column(type: 'datetime_immutable', nullable: true)]
    private ?\DateTimeInterface $readAt = null;

    public function __construct(ConversationItem $conversationItem, User $recipient, string $reason = self::REASON_GROUP)
    {
        $this->uuid = Uuid::v7();
        $this->conversationItem = $conversationItem;
        $this->recipient = $recipient;
        $this->reason = $reason;
        $this->createdAt = new \DateTimeImmutable();
    }

    public function getUuid(): Uuid
    {
        return $this->uuid;
    }

    public function getConversationItem(): ConversationItem
    {
        return $this->conversationItem;
    }

    public function getRecipient(): User
    {
        return $this->recipient;
    }

    public function getReason(): string
    {
        return $this->reason;
    }

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

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

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

    public function markRead(): void
    {
        $this->readAt ??= new \DateTimeImmutable();
    }
}
