<?php
namespace Opentalent\OtCore\Domain\Model;

use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

/**
 * Event
 */
class Event extends AbstractEntity
{
    /**
     * id
     *
     * @var int
     */
    protected $id;

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

    /**
     * organizationId
     *
     * @var int
     */
    protected $organizationId;

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

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

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

    /**
     * categories
     *
     * @var array
     */
    protected $categories;

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

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

    /**
     * datetimeStart
     *
     * @var \DateTime
     */
    protected $datetimeStart;

    /**
     * datetimeEnd
     *
     * @var \DateTime
     */
    protected $datetimeEnd;

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

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

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

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

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

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

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

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

    /**
     * longitude
     *
     * @var float
     */
    protected $longitude;

    /**
     * latitude
     *
     * @var float
     */
    protected $latitude;

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

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

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

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

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

    /**
     * zupId
     *
     * @var int
     */
    protected $zupId;

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

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

    /**
     * priceMini
     *
     * @var float
     */
    protected $priceMini;

    /**
     * meetingSchedule
     *
     * @var array
     */
    protected $meetingSchedule;

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

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

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

    /**
     * organization
     *
     * @var Organization
     */
    protected $organization = null;

    /**
     * Returns the id
     *
     * @return int $id
     */
    public function getId(): int
    {
        return $this->id;
    }

    /**
     * Sets the id
     *
     * @param int $id
     * @return void
     */
    public function setId(int $id)
    {
        $this->id = $id;
    }

    /**
     * Returns the type
     *
     * @return string $type
     */
    public function getType(): ?string
    {
        return $this->type;
    }

    /**
     * Sets the type
     *
     * @param string|null $type
     * @return void
     */
    public function setType(?string $type)
    {
        $this->type = $type;
    }

    /**
     * Returns the organizationId
     *
     * @return int $organizationId
     */
    public function getOrganizationId(): int
    {
        return $this->organizationId;
    }

    /**
     * Sets the organizationId
     *
     * @param int $organizationId
     * @return void
     */
    public function setOrganizationId(int $organizationId)
    {
        $this->organizationId = $organizationId;
    }

    /**
     * Returns the subdomain
     *
     * @return string $subdomain
     */
    public function getSubdomain(): ?string
    {
        return $this->subdomain;
    }

    /**
     * Sets the subdomain
     *
     * @param string|null $subdomain
     * @return void
     */
    public function setSubdomain(?string $subdomain)
    {
        $this->subdomain = $subdomain;
    }

    /**
     * Returns the name
     *
     * @return string $name
     */
    public function getName(): ?string
    {
        return $this->name;
    }

    /**
     * Sets the name
     *
     * @param string|null $name
     * @return void
     */
    public function setName(?string $name)
    {
        $this->name = $name;
    }

    /**
     * Returns the description
     *
     * @return string $description
     */
    public function getDescription(): ?string
    {
        return $this->description;
    }

    /**
     * Sets the description
     *
     * @param string|null $description
     * @return void
     */
    public function setDescription(?string $description)
    {
        $this->description = $description;
    }

    /**
     * Returns the categories
     *
     * @return array $categories
     */
    public function getCategories(): ?array
    {
        return $this->categories;
    }

    /**
     * Sets the categories
     *
     * @param array|null $categories
     * @return void
     */
    public function setCategories(?array $categories)
    {
        $this->categories = $categories;
    }

    /**
     * Returns the url
     *
     * @return string $url
     */
    public function getUrl(): ?string
    {
        return $this->url;
    }

    /**
     * Sets the url
     *
     * @param string|null $url
     * @return void
     */
    public function setUrl(?string $url)
    {
        $this->url = $url;
    }

    /**
     * Returns the rule
     *
     * @return string $rule
     */
    public function getRule(): ?string
    {
        return $this->rule;
    }

    /**
     * Sets the rule
     *
     * @param string|null $rule
     * @return void
     */
    public function setRule(?string $rule)
    {
        $this->rule = $rule;
    }

    /**
     * Returns the datetimeStart
     *
     * @return \DateTime $datetimeStart
     */
    public function getDatetimeStart(): ?\DateTime
    {
        return $this->datetimeStart;
    }

    /**
     * Sets the datetimeStart
     *
     * @param \DateTime|null $datetimeStart
     * @return void
     */
    public function setDatetimeStart(?\DateTime $datetimeStart)
    {
        $this->datetimeStart = $datetimeStart;
    }

    /**
     * Returns the datetimeEnd
     *
     * @return \DateTime $datetimeEnd
     */
    public function getDatetimeEnd(): ?\DateTime
    {
        return $this->datetimeEnd;
    }

    /**
     * Sets the datetimeEnd
     *
     * @param \DateTime|null $datetimeEnd
     * @return void
     */
    public function setDatetimeEnd(?\DateTime $datetimeEnd)
    {
        $this->datetimeEnd = $datetimeEnd;
    }

    /**
     * Returns the dates
     *
     * @return string $dates
     */
    public function getDates(): ?string
    {
        return $this->dates;
    }

    /**
     * Sets the dates
     *
     * @param string|null $dates
     * @return void
     */
    public function setDates(?string $dates)
    {
        $this->dates = $dates;
    }

    /**
     * Returns the placename
     *
     * @return string $placename
     */
    public function getPlacename(): ?string
    {
        return $this->placename;
    }

    /**
     * Sets the placename
     *
     * @param string|null $placename
     * @return void
     */
    public function setPlacename(?string $placename)
    {
        $this->placename = $placename;
    }

    /**
     * Returns the placeDescription
     *
     * @return string $placeDescription
     */
    public function getPlaceDescription(): ?string
    {
        return $this->placeDescription;
    }

    /**
     * Sets the placeDescription
     *
     * @param string|null $placeDescription
     * @return void
     */
    public function setPlaceDescription(?string $placeDescription)
    {
        $this->placeDescription = $placeDescription;
    }

    /**
     * Returns the placeFloorSize
     *
     * @return string $placeFloorSize
     */
    public function getPlaceFloorSize(): ?string
    {
        return $this->placeFloorSize;
    }

    /**
     * Sets the placeFloorSize
     *
     * @param string|null $placeFloorSize
     * @return void
     */
    public function setPlaceFloorSize(?string $placeFloorSize)
    {
        $this->placeFloorSize = $placeFloorSize;
    }

    /**
     * Returns the placeCapacity
     *
     * @return string $placeCapacity
     */
    public function getPlaceCapacity(): ?string
    {
        return $this->placeCapacity;
    }

    /**
     * Sets the placeCapacity
     *
     * @param string|null $placeCapacity
     * @return void
     */
    public function setPlaceCapacity(?string $placeCapacity)
    {
        $this->placeCapacity = $placeCapacity;
    }

    /**
     * Returns the city
     *
     * @return string $city
     */
    public function getCity(): ?string
    {
        return $this->city;
    }

    /**
     * Sets the city
     *
     * @param string|null $city
     * @return void
     */
    public function setCity(?string $city)
    {
        $this->city = $city;
    }

    /**
     * Returns the postalCode
     *
     * @return string $postalCode
     */
    public function getPostalCode(): ?string
    {
        return $this->postalCode;
    }

    /**
     * Sets the postalCode
     *
     * @param string|null $postalCode
     * @return void
     */
    public function setPostalCode(?string $postalCode)
    {
        $this->postalCode = $postalCode;
    }

    /**
     * Returns the streetAddress
     *
     * @return string $streetAddress
     */
    public function getStreetAddress(): ?string
    {
        return $this->streetAddress;
    }

    /**
     * Sets the streetAddress
     *
     * @param string|null $streetAddress
     * @return void
     */
    public function setStreetAddress(?string $streetAddress)
    {
        $this->streetAddress = $streetAddress;
    }

    /**
     * Returns the longitude
     *
     * @return float $longitude
     */
    public function getLongitude(): ?float
    {
        return $this->longitude;
    }

    /**
     * Sets the longitude
     *
     * @param float|null $longitude
     * @return void
     */
    public function setLongitude(?float $longitude)
    {
        $this->longitude = $longitude;
    }

    /**
     * Returns the latitude
     *
     * @return float $latitude
     */
    public function getLatitude(): ?float
    {
        return $this->latitude;
    }

    /**
     * Sets the latitude
     *
     * @param float|null $latitude
     * @return void
     */
    public function setLatitude(?float $latitude)
    {
        $this->latitude = $latitude;
    }

    /**
     * Returns the roomName
     *
     * @return string $roomName
     */
    public function getRoomName(): ?string
    {
        return $this->roomName;
    }

    /**
     * Sets the roomName
     *
     * @param string|null $roomName
     * @return void
     */
    public function setRoomName(?string $roomName)
    {
        $this->roomName = $roomName;
    }

    /**
     * Returns the roomDescription
     *
     * @return string $roomDescription
     */
    public function getRoomDescription(): ?string
    {
        return $this->roomDescription;
    }

    /**
     * Sets the roomDescription
     *
     * @param string|null $roomDescription
     * @return void
     */
    public function setRoomDescription(?string $roomDescription)
    {
        $this->roomDescription = $roomDescription;
    }

    /**
     * Returns the roomLocalisation
     *
     * @return string $roomLocalisation
     */
    public function getRoomLocalisation(): ?string
    {
        return $this->roomLocalisation;
    }

    /**
     * Sets the roomLocalisation
     *
     * @param string|null $roomLocalisation
     * @return void
     */
    public function setRoomLocalisation(?string $roomLocalisation)
    {
        $this->roomLocalisation = $roomLocalisation;
    }

    /**
     * Returns the roomCapacity
     *
     * @return string $roomCapacity
     */
    public function getRoomCapacity(): ?string
    {
        return $this->roomCapacity;
    }

    /**
     * Sets the roomCapacity
     *
     * @param string|null $roomCapacity
     * @return void
     */
    public function setRoomCapacity(?string $roomCapacity)
    {
        $this->roomCapacity = $roomCapacity;
    }

    /**
     * Returns the roomFloorSize
     *
     * @return string $roomFloorSize
     */
    public function getRoomFloorSize(): ?string
    {
        return $this->roomFloorSize;
    }

    /**
     * Sets the roomFloorSize
     *
     * @param string|null $roomFloorSize
     * @return void
     */
    public function setRoomFloorSize(?string $roomFloorSize)
    {
        $this->roomFloorSize = $roomFloorSize;
    }

    /**
     * Returns the zupId
     *
     * @return int $zupId
     */
    public function getZupId(): ?int
    {
        return $this->zupId;
    }

    /**
     * Sets the zupId
     *
     * @param int|null $zupId
     * @return void
     */
    public function setZupId(?int $zupId)
    {
        $this->zupId = $zupId;
    }

    /**
     * Returns the deepLink
     *
     * @return string $deepLink
     */
    public function getDeepLink(): ?string
    {
        return $this->deepLink;
    }

    /**
     * Sets the deepLink
     *
     * @param string|null $deepLink
     * @return void
     */
    public function setDeepLink(?string $deepLink)
    {
        $this->deepLink = $deepLink;
    }

    /**
     * Returns the image
     *
     * @return string $image
     */
    public function getImage(): ?string
    {
        return $this->image;
    }

    /**
     * Sets the image
     *
     * @param string|null $image
     * @return void
     */
    public function setImage(?string $image)
    {
        $this->image = $image;
    }

    /**
     * Returns the priceMini
     *
     * @return float $priceMini
     */
    public function getPriceMini(): ?float
    {
        return $this->priceMini;
    }

    /**
     * Sets the priceMini
     *
     * @param float|null $priceMini
     * @return void
     */
    public function setPriceMini(?float $priceMini)
    {
        $this->priceMini = $priceMini;
    }

    /**
     * Returns the meetingSchedule
     *
     * @return array $meetingSchedule
     */
    public function getMeetingSchedule(): ?array
    {
        return $this->meetingSchedule;
    }

    /**
     * Sets the meetingSchedule
     *
     * @param array|null $meetingSchedule
     * @return void
     */
    public function setMeetingSchedule(?array $meetingSchedule)
    {
        $this->meetingSchedule = $meetingSchedule;
    }

    /**
     * Returns the api
     *
     * @return bool $api
     */
    public function getApi(): ?bool
    {
        return $this->api;
    }

    /**
     * Sets the api
     *
     * @param bool $api
     * @return void
     */
    public function setApi(?bool $api)
    {
        $this->api = $api;
    }

    /**
     * Returns the boolean state of api
     *
     * @return bool
     */
    public function isApi(): ?bool
    {
        return $this->api;
    }

    /**
     * Returns the parentName
     *
     * @return string $parentName
     */
    public function getParentName(): ?string
    {
        return $this->parentName;
    }

    /**
     * Sets the parentName
     *
     * @param string|null $parentName
     * @return void
     */
    public function setParentName(?string $parentName)
    {
        $this->parentName = $parentName;
    }

    /**
     * Returns the parentSubdomain
     *
     * @return string $parentSubdomain
     */
    public function getParentSubdomain(): ?string
    {
        return $this->parentSubdomain;
    }

    /**
     * Sets the parentSubdomain
     *
     * @param string|null $parentSubdomain
     * @return void
     */
    public function setParentSubdomain(?string $parentSubdomain)
    {
        $this->parentSubdomain = $parentSubdomain;
    }

    /**
     * Returns the organization
     *
     * @return Organization $organization
     */
    public function getOrganization(): Organization
    {
        return $this->organization;
    }

    /**
     * Sets the organization
     *
     * @param Organization $organization
     * @return void
     */
    public function setOrganization(Organization $organization)
    {
        $this->organization = $organization;
    }


    /**
     *  Retourne une chaine formatée indiquant la date et l'heure de début et de fin de l'Event
     *
     * @return string
     */
    public function getFormattedDates(): string
    {
        $formattedDates = '';
        if ($this->getDatetimeStart() !== null & $this->getDatetimeEnd() !== null) {
            if ($this->getDatetimeStart()->format('d-m-Y') != $this->getDatetimeEnd()->format('d-m-Y')) {
                $formattedDates = 'Du ' . $this->getDatetimeStart()->format('d/m/Y H\hi') . ' au ' . $this->getDatetimeEnd()->format('d/m/Y H\hi');
            } else {
                $formattedDates = 'Le ' . $this->getDatetimeStart()->format('d/m/Y') . ' de ' . $this->getDatetimeStart()->format('H\hi') . ' à ' . $this->getDatetimeEnd()->format('H\hi');
            }
        } else if ($this->getDatetimeStart()) {
            $formattedDates = 'A partir du ' . $this->getDatetimeStart()->format('d/m/Y H\hi');
        } else if ($this->getDatetimeEnd()) {
            $formattedDates = "Jusqu'au " . $this->getDatetimeEnd()->format('d/m/Y H\hi');
        }
        return trim($formattedDates);
    }


    /**
     * Returns the short concatened location and date of the event
     *
     * @return string $datetimeStart
     */
    public function getLocAndDate(): string
    {
        $infos = [];

        if ($this->getPlacename() && $this->getCity() && ($this->getPlacename() !== $this->getCity())) {
            $infos[] = $this->getPlacename() . ' (' . $this->getCity() . ')';
        } else if ($this->getPlacename()) {
            $infos[] = $this->getPlacename();
        } else if ($this->getCity()) {
            $infos[] = $this->getCity();
        }
        $dates = $this->getFormattedDates();
        if ($dates !== '') {
            $infos[] = lcfirst($dates);
        }
        return ucfirst(join(', ', $infos));
    }


    /**
     * Returns the concatenated address of the event
     *
     * @return string
     */
    public function getFullAddress(string $delimiter=PHP_EOL): string
    {
        $address = [];

        if ($this->getPlaceName() &&
            strtolower($this->getPlaceName()) != strtolower($this->getStreetAddress()) &&
            strtolower($this->getPlaceName()) != strtolower($this->getCity())) {
            // On ajoute le nom du lieu, si ce n'est pas celui de la ville ou d'une adresse telle qu'une place
            $address[] = $this->getPlaceName();
        }
        if ($this->getRoomName() !== null) {
            $address[] = $this->getRoomName();
        }
        if ($this->getRoomLocalisation() !== null) {
            $address[] = $this->getRoomLocalisation();
        }
        if ($this->getStreetAddress() !== null) {
            $address[] = $this->getStreetAddress();
        }

        if ($this->getCity() !== null) {
            $pc = '';
            if ($this->getPostalCode() !== null) {
                $pc = $this->getPostalCode() . ' ';
            }
            $address[] = $pc . $this->getCity();
        }
        return trim(ucfirst(join($delimiter, $address)));
    }

    /**
     * Returns the inline concatenated address of the event
     *
     * @return string
     */
    public function getInlineFullAddress() {
        return $this->getFullAddress(', ');
    }

    /**
     * Returns an array containing all the data to display
     *
     * @return array
     */
    public function getInfosTable(): array
    {
        $infos = [];
        if ($this->getPlacename() !== null) {
            $infos['Lieu'] = $this->getPlacename();
        }
        if ($this->getPlaceDescription() !== null) {
            $infos['Description du lieu'] = $this->getPlaceDescription();
        }
        $address = $this->getFullAddress();
        if ($address !== '') {
            $infos['Adresse'] = $address;
        }
        if ($this->getUrl() !== null) {
            $infos['Lien externe'] = $this->getUrl();
        }
        return $infos;
    }

    /**
     * Returns an eluded description (max 100cars)
     *
     * @return string
     */
    public function getShortDescription(): string
    {
        $maxCars = 100;
        if ($this->getDescription() == null) {
            return "";
        } elseif (strlen($this->getDescription()) <= $maxCars) {
            return $this->getDescription();
        } else {
            $shorten = mb_substr($this->getDescription(), 0, $maxCars, "UTF-8");
            $shorten = trim($shorten);
            return $shorten . '...';
        }
    }

    /**
     * Returns a external url to get more informations
     * about an event (child-structures events only)
     */
    public function getInfosLink(): ?string
    {
        if (preg_match('#^((https?|ftp)://(\S*?\.\S*?))([\s)\[\]{},;"\':<]|\.\s|$)$#i', $this->getUrl()) == 1) {
            return $this->getUrl();
        } else if ($this->getSubdomain() !== null) {
            return 'https://' . $this->getSubdomain() . '.opentalent.fr';
        } else {
            return "";
        }
    }

}
