<?php

namespace AppBundle\Entity\Booking;

use AppBundle\Entity\Message\Message;
use AppBundle\Entity\Place\PlaceSystem;
use AppBundle\Enum\Booking\ParticipationStatusEnum;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Dunglas\ApiBundle\Annotation\Iri;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;

use AppBundle\Entity\Core\File;
use AppBundle\Validator\Constraints\Delete as OpentalentDelete;
use AppBundle\Validator\Constraints\Booking as OpentalentEvent;
use AppBundle\Entity\Place\Place;

/**
 * Evènement, rencontre
 *
 * @Iri("http://schema.org/Event")
 * @OpentalentDelete\EntityDelete()
 * @OpentalentEvent\Event()
 */
#[ORM\Entity(repositoryClass: 'AppBundle\Entity\Booking\Repository\EventRepository')]
class Event extends AbstractBooking
{
    /**
     * @var ArrayCollection<EventRecur>
     */
    #[Assert\Valid]
    #[ORM\OneToMany(targetEntity: 'EventRecur', mappedBy: 'event', cascade: ['persist'], orphanRemoval: true)]
    #[Groups(['event_bookingrecur', 'planning_detail', 'booking_event'])]
    protected $eventRecur;
    /**
     * @var ArrayCollection<Event>
     */
    #[ORM\OneToMany(targetEntity: 'Event', mappedBy: 'parent', orphanRemoval: true)]
    #[Groups(['event_timeline'])]
    private $timeline;
    /**
     * @var \AppBundle\Entity\Booking\Event
     */
    #[ORM\ManyToOne(targetEntity: 'Event', inversedBy: 'timeline')]
    #[Groups(['event'])]
    private $parent;
    /**
     * @var string
     */
    #[Assert\Type(type: 'string')]
    #[Assert\Choice(callback: ['\AppBundle\Enum\Booking\EventTimelineTypeEnum', 'toArray'], multiple: false, min: 1)]
    #[ORM\Column(type: 'string', length: 255, nullable: true)]
    #[Groups(['event', 'booking_event'])]
    private $type;
    /**
     * @var File An image of the item. This can be a [URL](http://schema.org/URL) or a fully described [ImageObject](http://schema.org/ImageObject).
     * @Iri("https://schema.org/image")
     */
    #[Assert\Valid]
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\Core\File', inversedBy: 'events', cascade: ['persist'])]
    #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
    #[Groups(['event', 'booking_event', 'planning_detail', 'invitations_list_event', 'event_details', 'activity_reports'])]
    private $image;
    /**
     * @var string URL of the item.
     *
     * @Iri("https://schema.org/url")
     */
    #[ORM\Column(type: 'string', nullable: true)]
    #[Assert\Url]
    #[Assert\Regex(pattern: '/^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/', message: 'url-error')]
    #[Groups(['event', 'planning_detail', 'event_details', 'booking_event'])]
    private $url;
    /**
     * @var string
     */
    #[ORM\Column(type: 'text', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['event', 'event_details', 'booking_event', 'planning_detail'])]
    private $additionalInformation;
    /**
     * @var string
     */
    #[ORM\Column(type: 'string', nullable: false)]
    #[Assert\Type(type: 'string')]
    #[Assert\NotNull]
    #[Assert\Choice(callback: ['\AppBundle\Enum\Booking\VisibilityEnum', 'toArray'])]
    #[Groups(['event', 'planning_detail', 'event_details', 'booking_event'])]
    private $visibility;
    /**
     * @var string
     */
    #[ORM\Column(type: 'text', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['event', 'planning_detail'])]
    private $report;
    /**
     * @var string
     */
    #[ORM\Column(type: 'text', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['event', 'planning_detail'])]
    private $comment;
    /**
     * @var EventGender
     */
    #[ORM\ManyToOne(targetEntity: 'EventGender')]
    #[Groups(['event', 'booking_event', 'activity_report', 'planning_detail'])]
    private $gender;
    /**
     * @var ArrayCollection<EventUser>
     */
    #[Assert\Valid]
    #[ORM\OneToMany(targetEntity: 'EventUser', mappedBy: 'event', cascade: ['persist'], orphanRemoval: true)]
    #[Groups(['event_eventuser', 'planning_detail', 'presence_attendance', 'event_details'])]
    private $eventUser;
    /**
     * @var ArrayCollection<Medal>
     */
    #[Assert\Valid]
    #[ORM\OneToMany(targetEntity: 'EventUser', mappedBy: 'event', cascade: ['persist'], orphanRemoval: true, fetch: 'EXTRA_LAZY')]
    #[Groups(['event_details'])]
    #[ORM\OrderBy(['id' => 'DESC'])]
    private $eventUserFiltered;
    /**
     * @var array
     */
    #[ORM\Column(type: 'text', nullable: true)]
    #[Groups(['event', 'event_details', 'planning_detail', 'booking_event'])]
    private $rule = array();
    /**
     * @var ArrayCollection<Categories>
     */
    #[Assert\Valid]
    #[ORM\ManyToMany(targetEntity: '\AppBundle\Entity\Core\Categories', cascade: ['persist'])]
    #[Groups(['event_categories', 'planning_detail', 'event_details', 'booking_event'])]
    private $categories;
    /**
     * @var ArrayCollection<EventReport>
     */
    #[ORM\OneToMany(targetEntity: '\AppBundle\Entity\Booking\EventReport', mappedBy: 'event', orphanRemoval: true)]
    #[Groups(['event_eventreport', 'planning_detail', 'event_details'])]
    private $eventReports;
    /**
     * @var ArrayCollection<AppBundle\Entity\Core\File>.
     */
    #[ORM\ManyToMany(targetEntity: 'AppBundle\Entity\Core\File', cascade: ['persist'], orphanRemoval: true)]
    #[ORM\JoinTable(name: 'event_files', joinColumns: [], inverseJoinColumns: [])]
    #[ORM\JoinColumn(name: 'event_id', referencedColumnName: 'id', onDelete: 'cascade')]
    #[ORM\JoinColumn(name: 'file_id', referencedColumnName: 'id', onDelete: 'cascade')]
    #[Groups(['booking_event', 'booking_event_documents', 'event_details'])]
    private $files;
    /**
     * var ArrayCollection<AttendanceBooking>
     */
    #[Assert\Valid]
    #[ORM\OneToMany(targetEntity: 'AppBundle\Entity\Booking\AttendanceBooking', cascade: ['persist'], mappedBy: 'event', orphanRemoval: true)]
    #[ORM\JoinColumn(nullable: false)]
    #[Groups(['event_attendancebooking', 'presence_attendance', 'planning_detail', 'booking_event', 'event_details'])]
    private $attendanceBooking;
    /**
     * @var array
     */
    #[Groups(['planning_list', 'activity_report'])]
    private $scoreParticipation;
    /**
     * @var PlaceSystem
     */
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\Place\PlaceSystem')]
    #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
    #[Groups(['booking', 'event_details', 'invitations_list_event', 'planning_detail', 'booking_event'])]
    private $placeSystem;
    /**
     * @var int
     */
    #[ORM\Column(type: 'integer')]
    private $openAgendaId;
    /**
     * @var string URL of the tickets.
     *
     * @Iri("https://schema.org/url")
     */
    #[ORM\Column(type: 'string', nullable: true)]
    #[Assert\Url]
    #[Assert\Regex(pattern: '/^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/', message: 'url-error')]
    #[Groups(['event', 'planning_detail', 'event_details', 'booking_event'])]
    private $urlTicket;
    public function __construct() {
        parent::__construct();
        $this->eventUser = new ArrayCollection();
        $this->eventUserFiltered = new ArrayCollection();
        $this->categories = new ArrayCollection();
        $this->eventReport = new ArrayCollection();
        $this->files = new ArrayCollection();
        $this->attendanceBooking = new ArrayCollection();
    }
    /**
     * Sets image.
     *
     * @param string $image
     *
     * @return $this
     */
    public function setImage($image)
    {
        $this->image = $image;

        return $this;
    }
    /**
     * Gets image.
     *
     * @return string
     */
    public function getImage()
    {
        return $this->image;
    }
    /**
     * Sets url.
     *
     * @param string $url
     *
     * @return $this
     */
    public function setUrl($url)
    {
        $this->url = $url;

        return $this;
    }
    /**
     * Gets url.
     *
     * @return string
     */
    public function getUrl()
    {
        return $this->url;
    }
    /**
     * Sets additionalInformation.
     *
     * @param string $additionalInformation
     *
     * @return $this
     */
    public function setAdditionalInformation($additionalInformation)
    {
        $this->additionalInformation = $additionalInformation;

        return $this;
    }
    /**
     * Gets additionalInformation.
     *
     * @return string
     */
    public function getAdditionalInformation()
    {
        return $this->additionalInformation;
    }
    /**
     * Sets visibility.
     *
     * @param string $visibility
     *
     * @return $this
     */
    public function setVisibility($visibility)
    {
        $this->visibility = $visibility;

        return $this;
    }
    /**
     * Gets visibility.
     *
     * @return string
     */
    public function getVisibility()
    {
        return $this->visibility;
    }
    /**
     * Sets gender.
     *
     * @param EventGender $gender
     *
     * @return $this
     */
    public function setGender(EventGender $gender = null)
    {
        $this->gender = $gender;

        return $this;
    }
    /**
     * Gets gender.
     *
     * @return EventGender
     */
    public function getGender()
    {
        return $this->gender;
    }
    /**
     * @param EventUser $eventUser
     * @return $this
     */
    public function addEventUser(EventUser $eventUser)
    {
        $eventUser->setEvent($this);
        $this->eventUser[] = $eventUser;

        return $this;
    }
    /**
     * @param ArrayCollection $eventUsers
     * @return $this
     */
    public function setEventUser(ArrayCollection $eventUsers)
    {
        $this->eventUser = $eventUsers;
        return $this;
    }
    /**
     * @param EventUser $eventUser
     * @return $this
     */
    public function removeEventUser(EventUser $eventUser)
    {
        $this->eventUser->removeElement($eventUser);
        return $this;
    }
    /**
     * @return mixed
     */
    public function getEventUser()
    {
        return ($this->eventUser) ? array_values($this->eventUser->toArray()) : new ArrayCollection();
    }
    /**
     * Get donors
     *3
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getEventUserFiltered()
    {
        $users = new ArrayCollection();
        $usersIds = array();
        foreach ($this->eventUserFiltered as $eventU){
            if(!in_array($eventU->getGuest()->getId(), $usersIds) && count($usersIds) < 3){
                $users->add($eventU);
                $usersIds[] = $eventU->getGuest()->getId();
            }

        }
        return $users;
    }
    /**
     * @param string $rule
     * @return $this
     */
    public function setRule($rule)
    {
        $this->rule = $rule;

        return $this;
    }
    /**
     * @return array
     */
    public function getRule()
    {
        return $this->rule;
    }
    /**
     * Add category
     *
     * @param \AppBundle\Entity\Core\Categories $category
     *
     * @return Event
     */
    public function addCategory(\AppBundle\Entity\Core\Categories $category)
    {
        $this->categories[] = $category;

        return $this;
    }
    /**
     * Remove category
     *
     * @param \AppBundle\Entity\Core\Categories $category
     */
    public function removeCategory(\AppBundle\Entity\Core\Categories $category)
    {
        $this->categories->removeElement($category);
    }
    /**
     * Get categories
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getCategories()
    {
        return $this->categories;
    }
    /**
     * Add eventReport
     *
     * @param \AppBundle\Entity\Booking\EventReport $eventReport
     *
     * @return Event
     */
    public function addEventReport(\AppBundle\Entity\Booking\EventReport $eventReport)
    {
        $this->eventReports[] = $eventReport;

        return $this;
    }
    /**
     * Remove eventReport
     *
     * @param \AppBundle\Entity\Booking\EventReport $eventReport
     */
    public function removeEventReport(\AppBundle\Entity\Booking\EventReport $eventReport)
    {
        $this->eventReports->removeElement($eventReport);
    }
    /**
     * Get eventReports
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getEventReports()
    {
        return $this->eventReports;
    }
    /**
     * {@inheritdoc}
     */
    public function getParticipants() {
        $participants = new ArrayCollection();
        array_map(function (EventUser $eu) use ($participants) { $participants->add($eu->getGuest()->getPerson());}, $this->getEventUser());
        return $participants;
    }
    /**
     * Set type
     *
     * @param string $type
     *
     * @return Event
     */
    public function setType($type)
    {
        $this->type = $type;

        return $this;
    }
    /**
     * Get type
     *
     * @return string
     */
    public function getType()
    {
        return $this->type;
    }
    /**
     * Set report
     *
     * @param string $report
     *
     * @return Event
     */
    public function setReport($report)
    {
        $this->report = $report;

        return $this;
    }
    /**
     * Get report
     *
     * @return string
     */
    public function getReport()
    {
        return $this->report;
    }
    /**
     * Set comment
     *
     * @param string $comment
     *
     * @return Event
     */
    public function setComment($comment)
    {
        $this->comment = $comment;

        return $this;
    }
    /**
     * Get comment
     *
     * @return string
     */
    public function getComment()
    {
        return $this->comment;
    }
    /**
     * Add timeline
     *
     * @param \AppBundle\Entity\Booking\Event $timeline
     *
     * @return Event
     */
    public function addTimeline(\AppBundle\Entity\Booking\Event $timeline)
    {
        $this->timeline[] = $timeline;

        return $this;
    }
    /**
     * Remove timeline
     *
     * @param \AppBundle\Entity\Booking\Event $timeline
     */
    public function removeTimeline(\AppBundle\Entity\Booking\Event $timeline)
    {
        $this->timeline->removeElement($timeline);
    }
    /**
     * Get timeline
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getTimeline()
    {
        return $this->timeline;
    }
    /**
     * Set parent
     *
     * @param \AppBundle\Entity\Booking\Event $parent
     *
     * @return Event
     */
    public function setParent(\AppBundle\Entity\Booking\Event $parent = null)
    {
        $this->parent = $parent;

        return $this;
    }
    /**
     * Get parent
     *
     * @return \AppBundle\Entity\Booking\Event
     */
    public function getParent()
    {
        return $this->parent;
    }
    /**
     * Add attendanceBooking
     *
     * @param \AppBundle\Entity\Booking\AttendanceBooking $attendanceBooking
     *
     * @return AbstractBooking
     */
    public function addAttendanceBooking(\AppBundle\Entity\Booking\AttendanceBooking $attendanceBooking)
    {
        $attendanceBooking->setEvent($this);
        $this->attendanceBooking[] = $attendanceBooking;

        return $this;
    }
    /**
     * Remove attendanceBooking
     *
     * @param \AppBundle\Entity\Booking\AttendanceBooking $attendanceBooking
     */
    public function removeAttendanceBooking(\AppBundle\Entity\Booking\AttendanceBooking $attendanceBooking)
    {
        $this->attendanceBooking->removeElement($attendanceBooking);
    }
    /**
     * Get attendanceBooking
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getAttendanceBooking()
    {
        return $this->attendanceBooking;
    }
    /**
     * @return array
     */
    public function getScoreParticipation()
    {
        return $this->scoreParticipation;
    }
    /**
     * @param array $scoreParticipation
     */
    public function setScoreParticipation(array $scoreParticipation)
    {
        $this->scoreParticipation = $scoreParticipation;
    }
    /**
     * Set place system
     *
     * @param \AppBundle\Entity\Place\PlaceSystem $placeSytem
     *
     * @return AbstractBooking
     */
    public function setPlaceSystem(\AppBundle\Entity\Place\PlaceSystem $placeSystem = null)
    {
        $this->placeSystem = $placeSystem;

        return $this;
    }
    /**
     * Get place
     *
     * @return \AppBundle\Entity\Place\PlaceSystem
     */
    public function getPlaceSystem()
    {
        return $this->placeSystem;
    }
    /**
     * Add file
     *
     * @param \AppBundle\Entity\Core\File $file
     *
     * @return Message
     */
    public function addFile(\AppBundle\Entity\Core\File $file)
    {
        $this->files[] = $file;

        return $this;
    }
    /**
     * Remove file
     *
     * @param \AppBundle\Entity\Core\File $file
     */
    public function removeFile(\AppBundle\Entity\Core\File $file)
    {
        $this->files->removeElement($file);
    }
    /**
     * Get files
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getFiles()
    {
        return $this->files;
    }
    /**
     * Sets open agenda ID.
     *
     * @param string $openAgendaId
     *
     * @return $this
     */
    public function setOpenagendaId($openAgendaId)
    {
        $this->openAgendaId = $openAgendaId;

        return $this;
    }
    /**
     * Gets open agenda Id.
     *
     * @return string
     */
    public function getOpenAgendaId()
    {
        return $this->openAgendaId;
    }
    /**
     * Sets url ticket.
     *
     * @param string $urlTicket
     *
     * @return $this
     */
    public function setUrlTicket($urlTicket)
    {
        $this->urlTicket = $urlTicket;

        return $this;
    }
    /**
     * Gets url ticket.
     *
     * @return string
     */
    public function getUrlTicket()
    {
        return $this->urlTicket;
    }
}
