<?php

namespace Ig\IgReservations\Domain\Model;

use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use DateTime;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;

/**
 * Reservation
 */
class Reservation extends AbstractEntity
{
    /**
     * event
     *
     * @var Event
     */
    protected $event = null;

    /**
     * language
     *
     * @var int
     */
    protected $language = 0;

    /**
     * purpose
     *
     * @var Purpose
     */
    protected $purpose = null;

    /**
     * frontendUser
     *
     * @var FeUser
     */
    protected $frontendUser = null;

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

    /**
     * salutation
     *
     * @var int
     */
    protected $salutation = 0;

    /**
     * firstName
     *
     * @var string
     */
    protected $firstName = '';

    /**
     * lastName
     *
     * @var string
     */
    protected $lastName = '';

    /**
     * company
     *
     * @var string
     */
    protected $company = '';

    /**
     * address
     *
     * @var string
     */
    protected $address = '';

    /**
     * zip
     *
     * @var string
     */
    protected $zip = '';

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

    /**
     * email
     *
     * @var string
     */
    protected $email = '';

    /**
     * phone
     *
     * @var string
     */
    protected $phone = '';

    /**
     * address
     *
     * @var string
     */
    protected $companyAddress = '';

    /**
     * zip
     *
     * @var string
     */
    protected $companyZip = '';

    /**
     * city
     *
     * @var string
     */
    protected $companyCity = '';

    /**
     * companyPhone
     *
     * @var string
     */
    protected $companyPhone = '';

    /**
     * address
     *
     * @var boolean
     */
    protected $hasBillAddress = false;

    /**
     * name
     *
     * @var string
     */
    protected $billName = '';

    /**
     * address
     *
     * @var string
     */
    protected $billAddress = '';

    /**
     * zip
     *
     * @var string
     */
    protected $billZip = '';

    /**
     * city
     *
     * @var string
     */
    protected $billCity = '';

    /**
     * confirmed
     *
     * @var boolean
     */
    protected $confirmed = false;

    /**
     * reminderSent
     *
     * @var boolean
     */
    protected bool $reminderSent = false;

    /**
     * reservationType
     *
     * @var ReservationType
     */
    protected $reservationType = null;

    /**
     * notes
     *
     * @var string
     */
    protected $notes = '';

    /**
     * @var DateTime
     */
    protected $crdate;

    /**
     * Get the value of event
     *
     * @return Event
     */
    public function getEvent()
    {
        return $this->event;
    }

    /**
     * Set the value of event
     *
     * @return self
     */
    public function setEvent(Event $event)
    {
        $this->event = $event;

        return $this;
    }

    /**
     * Get the value of frontendUser
     *
     * @return FeUser
     */
    public function getFrontendUser()
    {
        return $this->frontendUser;
    }

    /**
     * Set the value of frontendUser
     *
     * @return self
     */
    public function setFrontendUser(FeUser $frontendUser = null)
    {
        $this->frontendUser = $frontendUser;

        return $this;
    }

    /**
     * Get the value of purpose
     *
     * @return FeUser
     */
    public function getPurpose()
    {
        return $this->purpose;
    }

    /**
     * Set the value of purpose
     *
     * @return self
     */
    public function setPurpose(Purpose $purpose = null)
    {
        $this->purpose = $purpose;

        return $this;
    }

    public function getIsMe()
    {
        $context = GeneralUtility::makeInstance(Context::class);
        $frontendUserId = $context->getPropertyFromAspect('frontend.user', 'id');

        if (!$frontendUserId || !$this->frontendUser) {
            return false;
        }

        if ($frontendUserId == $this->getFrontendUser()->getUid()) {
            return true;
        }

        return false;
    }

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

    /**
     * Returns the sort string for event output
     *
     * @return string string to sort output for customer
     */
    public function getSort()
    {
        if ($this->frontendUser) {
            return $this->frontendUser->getLastName() . ' ' . $this->frontendUser->getFirstName();
        }
        return $this->name;
    }

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

    /**
     * Returns the firstName
     *
     * @return string
     */
    public function getFirstName()
    {
        return $this->firstName;
    }

    /**
     * Sets the firstName
     *
     * @param string $firstName
     */
    public function setFirstName($firstName): void
    {
        $this->firstName = $firstName;
    }

    /**
     * Returns the lastName
     *
     * @return string
     */
    public function getLastName()
    {
        return $this->lastName;
    }

    /**
     * Sets the lastName
     *
     * @param string $lastName
     */
    public function setLastName($lastName): void
    {
        $this->lastName = $lastName;
    }

    /**
     * Returns the company
     *
     * @return string
     */
    public function getCompany()
    {
        return $this->company;
    }

    /**
     * Sets the company
     *
     * @param string $company
     */
    public function setCompany($company): void
    {
        $this->company = $company;
    }

    /**
     * Returns the address
     *
     * @return string
     */
    public function getAddress()
    {
        return $this->address;
    }

    /**
     * Sets the address
     *
     * @param string $address
     */
    public function setAddress($address): void
    {
        $this->address = $address;
    }

    /**
     * Returns the zip
     *
     * @return string
     */
    public function getZip()
    {
        return $this->zip;
    }

    /**
     * Sets the zip
     *
     * @param string $zip
     */
    public function setZip($zip): void
    {
        $this->zip = $zip;
    }

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

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

    /**
     * Returns the email
     *
     * @return string
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Sets the email
     *
     * @param string $email
     */
    public function setEmail($email): void
    {
        $this->email = $email;
    }

    /**
     * Returns the phone
     *
     * @return string
     */
    public function getPhone()
    {
        return $this->phone;
    }

    /**
     * Sets the phone
     *
     * @param string $phone
     */
    public function setPhone($phone): void
    {
        $this->phone = $phone;
    }

    /**
     * Returns the salutation
     *
     * @return int
     */
    public function getSalutation()
    {
        return $this->salutation;
    }

    /**
     * Sets the salutation
     *
     * @param int $salutation
     */
    public function setSalutation($salutation): void
    {
        $this->salutation = $salutation;
    }

    /**
     * Get the value of language
     *
     * @return int
     */
    public function getLanguage()
    {
        return $this->language;
    }

    /**
     * Set the value of language
     *
     * @param int $language
     *
     * @return self
     */
    public function setLanguage($language)
    {
        $this->language = $language;

        return $this;
    }

    /**
     * Returns the site language for the language of this Event
     *
     * @return SiteLanguage
     */
    public function getLanguageConfig()
    {
        $site = $GLOBALS['TYPO3_REQUEST']->getAttribute('site');
        return $site->getLanguageById($this->getLanguage());
    }
    
    public function getRawAddress()
    {
        $text = '';
        if ($this->getFirstName() || $this->getLastName()) {
            $text .= $this->getFirstName() . ' ' . $this->getLastName();
        }
        if ($this->getAddress()) {
            if ($text) {
                $text .= "\n";
            }
            $text .= $this->getAddress();
        }
        if ($this->getZip() || $this->getCity()) {
            if ($text) {
                $text .= "\n";
            }
            $text .= $this->getZip() . ' ' . $this->getCity();
        }

        return $text;
    }

    public function isEmpty()
    {
        return !$this->getFirstName()
            && !$this->getLastName()
            && !$this->getAddress()
            && !$this->getZip()
            && !$this->getCity()
            && !$this->getSalutation()
            && !$this->getPhone()
            && !$this->getCompany()
            && !$this->getEmail();
    }


    /**
     * Get the value of address
     *
     * @return string
     */
    public function getCompanyAddress()
    {
        return $this->companyAddress;
    }

    /**
     * Set the value of address
     *
     * @param string $companyAddress
     *
     * @return self
     */
    public function setCompanyAddress($companyAddress)
    {
        $this->companyAddress = $companyAddress;

        return $this;
    }

    /**
     * Get the value of zip
     *
     * @return string
     */
    public function getCompanyZip()
    {
        return $this->companyZip;
    }

    /**
     * Set the value of zip
     *
     * @param string $companyZip
     *
     * @return self
     */
    public function setCompanyZip($companyZip)
    {
        $this->companyZip = $companyZip;

        return $this;
    }

    /**
     * Get the value of city
     *
     * @return string
     */
    public function getCompanyCity()
    {
        return $this->companyCity;
    }

    /**
     * Set the value of city
     *
     * @param string $companyCity
     *
     * @return self
     */
    public function setCompanyCity($companyCity)
    {
        $this->companyCity = $companyCity;

        return $this;
    }

    /**
     * Get the value of name
     *
     * @return string
     */
    public function getBillName()
    {
        return $this->billName;
    }

    /**
     * Set the value of name
     *
     * @param string $billName
     *
     * @return self
     */
    public function setBillName($billName)
    {
        $this->billName = $billName;

        return $this;
    }

    /**
     * Get the value of address
     *
     * @return string
     */
    public function getBillAddress()
    {
        return $this->billAddress;
    }

    /**
     * Set the value of address
     *
     * @param string $billAddress
     *
     * @return self
     */
    public function setBillAddress($billAddress)
    {
        $this->billAddress = $billAddress;

        return $this;
    }

    /**
     * Get the value of zip
     *
     * @return string
     */
    public function getBillZip()
    {
        return $this->billZip;
    }

    /**
     * Set the value of zip
     *
     * @param string $billZip
     *
     * @return self
     */
    public function setBillZip($billZip)
    {
        $this->billZip = $billZip;

        return $this;
    }

    /**
     * Get the value of city
     *
     * @return string
     */
    public function getBillCity()
    {
        return $this->billCity;
    }

    /**
     * Set the value of city
     *
     * @param string $billCity
     *
     * @return self
     */
    public function setBillCity($billCity)
    {
        $this->billCity = $billCity;

        return $this;
    }


    /**
     * Get the value of address
     *
     * @return boolean
     */
    public function getHasBillAddress()
    {
        return $this->hasBillAddress;
    }

    /**
     * Set the value of address
     *
     * @param boolean $hasBillAddress
     *
     * @return self
     */
    public function setHasBillAddress($hasBillAddress)
    {
        $this->hasBillAddress = $hasBillAddress;

        return $this;
    }


    /**
     * Get the value of companyPhone
     *
     * @return string
     */
    public function getCompanyPhone()
    {
        return $this->companyPhone;
    }

    /**
     * Set the value of companyPhone
     *
     * @param string $companyPhone
     *
     * @return self
     */
    public function setCompanyPhone($companyPhone)
    {
        $this->companyPhone = $companyPhone;

        return $this;
    }

    public function getCanCancel()
    {
        $event = $this->getEvent();
        $calendar = $event->getCalendar();

        $acl = $calendar->getAcl();

        if ($acl->hasPermission('user')) {
            $startDateTime = $event->getStartDateTime();
            $cancelBeginDateTimeModifier = $acl->getCancelBeginDateTimeModifier();
            $cancelEndDateTimeModifier = $acl->getCancelEndDateTimeModifier();

            $cancelLowerLimit = null;
            $cancelUpperLimit = null;
            if ($cancelBeginDateTimeModifier && $cancelEndDateTimeModifier) {
                $cancelLowerLimit = new DateTime();
                $cancelLowerLimit->modify($cancelBeginDateTimeModifier);
                $cancelUpperLimit = new DateTime();
                $cancelUpperLimit->modify($cancelEndDateTimeModifier);

                if ($cancelLowerLimit < $startDateTime && $cancelUpperLimit > $startDateTime) {
                    return true;
                }
            } elseif ($cancelBeginDateTimeModifier) {
                $cancelLowerLimit = new DateTime();
                $cancelLowerLimit->modify($cancelBeginDateTimeModifier);

                if ($cancelLowerLimit < $startDateTime) {
                    return true;
                }
            } elseif ($cancelEndDateTimeModifier) {
                $cancelUpperLimit = new DateTime();
                $cancelUpperLimit->modify($cancelEndDateTimeModifier);

                if ($cancelUpperLimit > $startDateTime) {
                    return true;
                }
            }
        }

        return false;
    }


    /**
     * Get the value of confirmed
     *
     * @return boolean
     */
    public function getConfirmed()
    {
        return $this->confirmed;
    }

    /**
     * Set the value of confirmed
     *
     * @param boolean $confirmed
     *
     * @return self
     */
    public function setConfirmed($confirmed)
    {
        $this->confirmed = $confirmed;

        return $this;
    }

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

    public function setReminderSent(bool $reminderSent): void
    {
        $this->reminderSent = $reminderSent;
    }


    /**
     * Get the value of reservationType
     *
     * @return ReservationType
     */
    public function getReservationType()
    {
        return $this->reservationType;
    }

    /**
     * Set the value of reservationType
     *
     * @return self
     */
    public function setReservationType(ReservationType $reservationType)
    {
        $this->reservationType = $reservationType;

        return $this;
    }

    public function getReservationTypeForLanguage($language = 0)
    {
        if ($this->getReservationType() && $language > 0) {
            $uid = $this->getReservationType()
->getUid();

            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
                'tx_igreservations_domain_model_reservationtype'
            );
            $row = $queryBuilder->select('*')
                ->from('tx_igreservations_domain_model_reservationtype')
                ->where(
                    $queryBuilder->expr()
->orX($queryBuilder->expr() ->eq('uid', $uid), $queryBuilder->expr() ->eq('l10n_parent', $uid)),
                    $queryBuilder->expr()
->eq('sys_language_uid', $language)
                )
                ->execute()
                ->fetch();

            if ($row) {
                $res = $this->dataMapper->map(Status::class, [$row]);
                return $res[0];
            }
        }

        return $this->getReservationType();
    }


    /**
     * Get the value of notes
     *
     * @return string
     */
    public function getNotes()
    {
        return $this->notes;
    }

    /**
     * Set the value of notes
     *
     * @param string $notes
     *
     * @return self
     */
    public function setNotes($notes)
    {
        $this->notes = $notes;

        return $this;
    }

    public function getCrdate()
    {
        return $this->crdate;
    }

    public function setCrdate($crdate): void
    {
        $this->crdate = $crdate;
    }

    public function getGreeting(): string
    {
        $greeting = '';
        $reservationLanguage = $this->getLanguageConfig();
        $languageKey = $reservationLanguage->getTwoLetterIsoCode();
        if($this->getSalutation()) {
            $greeting .= LocalizationUtility::translate('tx_igreservations_domain_model_address.salutation.' . $this->getSalutation(), 'IgReservations', null, $languageKey);
        }
        /*if($this->getFirstName()) {
            if ($greeting != '') {
                $greeting .= ' ';
            }
            $greeting .= $this->getFirstName();
        }*/
        if($this->getLastName()) {
            if ($greeting != '') {
                $greeting .= ' ';
            }
            $greeting .= $this->getLastName();
        }
        return $greeting;
    }
}
