<?php declare(strict_types=1);
namespace Newland\Toubiz\Sync\Neos\Domain\Model;

/*
 * This file is part of the "toubiz-sync-neos" package.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 */

use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Neos\Flow\Annotations as Flow;
use Newland\Toubiz\Sync\Neos\Domain\Model\Traits\DeterministicPersistenceObjectIdentifier;
use Newland\Toubiz\Sync\Neos\Orm\Uuid\CustomUuidGeneration;
use Newland\Toubiz\Sync\Neos\Orm\Uuid\UuidGenerator;
use Newland\Toubiz\Sync\Neos\Translation\TranslatableEntity;
use Ramsey\Uuid\UuidInterface;

/**
 * A date/time an event is going on.
 *
 * @Flow\Entity
 * @ORM\Table(indexes={
 *      @ORM\Index(name="newland_toubiz_sync_neos_eventdate_import_ident", columns={"language", "originalid"})
 * })
 */
class EventDate extends AbstractEntity implements CustomUuidGeneration
{
    use TranslatableEntity;

    public function generateUuid(): UuidInterface
    {
        return UuidGenerator::uuidFromProperties(
            [
                $this->originalId,
                $this->language,
                $this->event->getClient(),
            ]
        );
    }

    /**
     * @var Event|null
     * @ORM\ManyToOne(inversedBy="eventDates")
     */
    protected $event;

    /**
     * @var DateTimeInterface|null
     * @ORM\Column(type="datetime", nullable=true)
     */
    protected $beginsAt;

    /** @var bool */
    protected $beginsAtSpecificTime = true;

    /**
     * @var DateTimeInterface|null
     * @ORM\Column(type="datetime", nullable=true)
     */
    protected $endsAt;

    /** @var bool */
    protected $endsAtSpecificTime = true;

    /** @var bool */
    protected $hasDate;

    /** @var string */
    protected $note;

    /**
     * @var string|null Specific detail URI for this event.
     * @ORM\Column(nullable=true)
     */
    protected $detailUri;

    /** @var bool */
    protected $hidden = false;

    /** @var bool */
    protected $cancelled = false;

    /** @var bool */
    protected $active = true;

    public function setEvent(?Event $event): void
    {
        $this->event = $event;
    }

    public function getEvent(): ?Event
    {
        return $this->event;
    }

    public function setBeginsAt(?DateTimeInterface $beginsAt): void
    {
        $this->beginsAt = $beginsAt;
    }

    public function getBeginsAt(): ?DateTimeInterface
    {
        return $this->beginsAt;
    }

    public function setEndsAt(?DateTimeInterface $endsAt): void
    {
        $this->endsAt = $endsAt;
    }

    public function getEndsAt(): ?DateTimeInterface
    {
        return $this->endsAt;
    }

    public function getEndsOnSameDay(): bool
    {
        if ($this->beginsAt === null || $this->endsAt === null) {
            return true;
        }

        return $this->beginsAt->format('Y-m-d') === $this->endsAt->format('Y-m-d');
    }

    public function getIsInThePast(): bool
    {
        // On demand events are considered to be in the future.
        if ($this->endsAt === null) {
            return false;
        }

        $today = new \DateTime;
        return $this->endsAt->getTimestamp() <= $today->getTimestamp();
    }

    public function setNote(string $note): void
    {
        $this->note = $note;
    }

    public function getNote(): string
    {
        return $this->note;
    }

    public function setDetailUri(?string $detailUri): void
    {
        $this->detailUri = $detailUri;
    }

    public function getDetailUri(): ?string
    {
        return $this->detailUri;
    }

    public function getBeginsAtSpecificTime(): bool
    {
        return $this->beginsAtSpecificTime;
    }

    public function setBeginsAtSpecificTime(bool $beginsAtSpecificTime): void
    {
        $this->beginsAtSpecificTime = $beginsAtSpecificTime;
    }

    public function getEndsAtSpecificTime(): bool
    {
        return $this->endsAtSpecificTime;
    }

    public function setEndsAtSpecificTime(bool $endsAtSpecificTime): void
    {
        $this->endsAtSpecificTime = $endsAtSpecificTime;
    }

    public function isHidden(): bool
    {
        return $this->hidden;
    }

    public function setHidden(bool $hidden): void
    {
        $this->hidden = $hidden;
    }

    public function isCancelled(): bool
    {
        return $this->cancelled;
    }

    public function setCancelled(bool $cancelled): void
    {
        $this->cancelled = $cancelled;
    }

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

    public function setActive(bool $active): void
    {
        $this->active = $active;
    }

    public function hasDate(): bool
    {
        return $this->hasDate;
    }

    public function setHasDate(bool $hasDate): void
    {
        $this->hasDate = $hasDate;
    }
}
