<?php

namespace AppBundle\Entity\Core;

use AppBundle\Annotation\ExportFilter;
use AppBundle\Annotation\ExportSplitFields;
use AppBundle\Entity\Organization\Organization;
use AppBundle\Entity\Person\Person;
use AppBundle\Entity\Place\Place;
use AppBundle\Enum\Core\ContactPointTypeEnum;
use Doctrine\ORM\Mapping as ORM;
use Dunglas\ApiBundle\Annotation\Iri;
use libphonenumber\PhoneNumber;
use libphonenumber\PhoneNumberUtil;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use AppBundle\Entity\Traits\TimestampableEntity;
use AppBundle\Entity\Traits\CreatorUpdaterEntity;
use AppBundle\Validator\Constraints as OpentalentAssert;
use AppBundle\Annotation\Confidentiality;
use Misd\PhoneNumberBundle\Validator\Constraints\PhoneNumber as AssertPhoneNumber;

/**
 * Données de contact d'une Person ou d'une Organization
 *
 * @Iri("http://schema.org/ContactPoint")
 */
#[ORM\Entity(repositoryClass: 'AppBundle\Entity\Core\Repository\ContactPointRepository')]
#[Assert\Callback(['AppBundle\Validator\Constraints\Core\ContactPointValidator', 'validate'])]
#[ORM\Table(name: 'ContactPoint')]
#[ORM\Index(name: 'email', columns: ['email'])]
class ContactPoint
{
    use TimestampableEntity;
    use CreatorUpdaterEntity;
    /**
     * @var int
     *
     * })
     */
    #[ORM\Column(type: 'integer')]
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    #[Groups(['contactpoint', 'othercontact_list_person', 'place_list', 'student_registration_person', 'student_registration_guardians', 'network_list', 'federations_list', 'networkmanagers_list_person', 'network_artist_school_list', 'organization_details', 'organization_cotisation_steps', 'online_registration_access_details_person', 'cmf_network_organizations'])]
    private $id;
    /**
     * @var string A person or organization can have different contact points, for different purposes. For example, a sales contact point, a PR contact point and so on. This property is used to specify the kind of contact point.
     *
     * @Iri("https://schema.org/contactType")
     */
    #[ORM\Column(type: 'string')]
    #[Assert\Type(type: 'string')]
    #[Assert\NotBlank(message: 'not-blank')]
    #[Assert\Choice(callback: ['\AppBundle\Enum\Core\ContactPointTypeEnum', 'toArray'], message: 'invalid-choice')]
    #[Groups(['contactpoint', 'access_details_person', 'access_details_guardians', 'report_card_person', 'report_card_guardians', 'student_registration_person', 'student_registration_guardians', 'network_list_contactpoint', 'federations_list_contactpoint', 'networkmanagers_list_person', 'network_artist_school_list_contactpoint', 'network_list_adminaccess', 'access_mail_person', 'student_list_guardians', 'access_mail_guardians', 'organization_details_contactpoint', 'payer_list_person', 'access_duplicate_control_list_person', 'organization_cotisation_steps_contactpoint', 'template', 'view_from_manager_create_person', 'online_registration_access_details_person', 'onlineregistration_infos_organization', 'accesses_no_reregistred_list_person', 'accesses_no_reregistred_list_guardians', 'cmf_network_organizations_contactpoint'])]
    private $contactType;
    /**
     * @var string Email address.
     *
     * @Iri("https://schema.org/email")
     * @Confidentiality(visibility=\AppBundle\Enum\Confidentiality\ConfidentialityTypeEnum::VISIBILITY_ORGANIZATION)
     */
    #[ORM\Column(type: 'string', length: 255, nullable: true)]
    #[Assert\Email(strict: true, message: 'invalid-email-format')]
    #[Assert\Email(checkMX: true, message: 'invalid-email-domain')]
    #[Assert\Regex(pattern: '/^[a-zA-Z0-9._%-]{1,64}@[a-zA-Z0-9.-]{2,249}\.[a-zA-Z]{2,20}$/', message: 'email-error')]
    #[Groups(['contactpoint', 'access_details_person', 'access_details_guardians', 'student_list_person', 'guardians_list_person', 'all_accesses_list_person', 'teachers_list_person', 'adherent_list_person', 'personnels_list_person', 'morals_list_person', 'ca_list_person', 'accesses_list_person', 'othercontact_list_person', 'place_list_contactpoint', 'report_card_person', 'report_card_guardians', 'student_registration_person', 'student_registration_guardians', 'board_list_person', 'network_list_contactpoint', 'federations_list_contactpoint', 'networkmanagers_list_person', 'network_artist_school_list_contactpoint', 'network_list_adminaccess', 'adherent_contact_person', 'adherent_contact_guardians', 'access_mail_person', 'student_list_guardians', 'access_mail_guardians', 'organization_details_contactpoint', 'payer_list_person', 'access_duplicate_control_list_person', 'organization_cotisation_steps_contactpoint', 'template', 'view_from_manager_create_person', 'online_registration_access_details_person', 'onlineregistration_infos_organization', 'accesses_no_reregistred_list_person', 'accesses_no_reregistred_list_guardians', 'cmf_network_organizations_contactpoint'])]
    private $email;
    /**
     * @var string Invalid Email address.
     *
     * @Iri("https://schema.org/email")
     */
    #[ORM\Column(type: 'string', length: 255, nullable: true)]
    #[Groups(['contactpoint'])]
    private $emailInvalid;
    /**
     * @var string The fax number.
     *
     * @AssertPhoneNumber
     * @Iri("https://schema.org/faxNumber")
     */
    #[ORM\Column(type: 'phone_number', nullable: true)]
    #[Groups(['contactpoint', 'access_details_person', 'access_duplicate_control_list_person', 'organization_cotisation_steps_contactpoint', 'organization_details_contactpoint'])]
    private $faxNumber;
    /**
     * @var string The invalid fax number.
     *
     * @Iri("https://schema.org/faxNumber")
     */
    #[ORM\Column(type: 'string', length: 255, nullable: true)]
    #[Groups(['contactpoint'])]
    private $faxNumberInvalid;
    /**
     * @var string
     *
     * @AssertPhoneNumber
     * @Confidentiality(visibility=\AppBundle\Enum\Confidentiality\ConfidentialityTypeEnum::VISIBILITY_ORGANIZATION)
     */
    #[ORM\Column(type: 'phone_number', nullable: true)]
    #[Groups(['contactpoint', 'access_details_person', 'access_details_guardians', 'student_list_person', 'guardians_list_person', 'teachers_list_person', 'adherent_list_person', 'personnels_list_person', 'morals_list_person', 'ca_list_person', 'accesses_list_person', 'othercontact_list_person', 'place_list_contactpoint', 'student_registration_person', 'student_registration_guardians', 'board_list_person', 'all_accesses_list_person', 'network_list_contactpoint', 'federations_list_contactpoint', 'networkmanagers_list_person', 'network_artist_school_list_contactpoint', 'adherent_contact_person', 'adherent_contact_guardians', 'student_list_guardians', 'organization_details_contactpoint', 'payer_list_person', 'access_duplicate_control_list_person', 'organization_cotisation_steps_contactpoint', 'view_from_manager_create_person', 'online_registration_access_details_person', 'onlineregistration_infos_organization', 'accesses_no_reregistred_list_person', 'accesses_no_reregistred_list_guardians', 'cmf_network_organizations_contactpoint'])]
    private $telphone;
    /**
     * @var string
     */
    #[ORM\Column(type: 'string', length: 255, nullable: true)]
    #[Groups(['contactpoint'])]
    private $telphoneInvalid;
    /**
     * @var string
     *
     * @AssertPhoneNumber
     * @Confidentiality(visibility=\AppBundle\Enum\Confidentiality\ConfidentialityTypeEnum::VISIBILITY_ORGANIZATION)
     */
    #[ORM\Column(type: 'phone_number', nullable: true)]
    #[Groups(['contactpoint', 'access_details_person', 'access_details_guardians', 'student_registration_person', 'student_registration_guardians', 'student_list_person', 'accesses_list_person', 'guardians_list_person', 'teachers_list_person', 'adherent_list_person', 'personnels_list_person', 'morals_list_person', 'ca_list_person', 'all_accesses_list_person', 'othercontact_list_person', 'board_list_person', 'student_list_guardians', 'network_list_contactpoint', 'federations_list_contactpoint', 'networkmanagers_list_person', 'organization_details_contactpoint', 'payer_list_person', 'adherent_contact_person', 'access_duplicate_control_list_person', 'organization_cotisation_steps_contactpoint', 'view_from_manager_create_person', 'online_registration_access_details_person', 'onlineregistration_infos_organization', 'accesses_no_reregistred_list_person', 'accesses_no_reregistred_list_guardians', 'cmf_network_organizations_contactpoint'])]
    private $mobilPhone;
    /**
     * @var string
     */
    #[ORM\Column(type: 'string', length: 255, nullable: true)]
    #[Groups(['contactpoint'])]
    private $mobilPhoneInvalid;
    /**
     * @var string
     * @ExportSplitFields({"email","telphoneTemplate","mobilPhoneTemplate"})
     */
    #[Groups(['template', 'place_list_contactpoint'])]
    private $fullLabelTemplate;
    /**
     * @var string
     */
    #[Groups(['template'])]
    private $telphoneTemplate;
    /**
     * @var string
     */
    #[Groups(['template'])]
    private $mobilPhoneTemplate;
    /**
     * @var Organization
     */
    #[ORM\ManyToMany(targetEntity: 'AppBundle\Entity\Organization\Organization', mappedBy: 'contactPoint')]
    private $organization;
    /**
     * @var Person
     */
    #[ORM\ManyToMany(targetEntity: 'AppBundle\Entity\Person\Person', mappedBy: 'contactPoint')]
    private $person;
    /**
     * @var Place
     */
    #[ORM\ManyToMany(targetEntity: 'AppBundle\Entity\Place\Place', mappedBy: 'contactpoint')]
    private $place;
    /**
     *
     * @var string
     */
    #[ORM\Column(type: 'text', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['contactpoint'])]
    private $invalidReason;
    /**
     *
     * @var string
     */
    #[ORM\Column(type: 'text', nullable: true)]
    #[Assert\Type(type: 'string')]
    private $invalidEmailBody;
    /**
     *
     * @var string
     */
    #[ORM\Column(type: 'string', length: 255, nullable: true)]
    #[Assert\Type(type: 'string')]
    private $invalidCat;
    /**
     *
     * @var string
     */
    #[ORM\Column(type: 'string', length: 255, nullable: true)]
    #[Assert\Type(type: 'string')]
    private $invalidStatus;
    /**
     * @var string
     * @ExportFilter({"contactType","PRINCIPAL"})
     * @ExportSplitFields({"email","telphoneTemplate","mobilPhoneTemplate"})
     */
    #[Groups(['template'])]
    private $fullLabelPrincipalTemplate;
    /**
     * @var string
     * @ExportFilter({"contactType","CONTACT"})
     * @ExportSplitFields({"email","telphoneTemplate","mobilPhoneTemplate"})
     */
    #[Groups(['template'])]
    private $fullLabelContactTemplate;
    /**
     * @var string
     * @ExportFilter({"contactType","BILL"})
     * @ExportSplitFields({"email","telphoneTemplate","mobilPhoneTemplate"})
     */
    #[Groups(['template'])]
    private $fullLabelBillTemplate;
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->organization = new \Doctrine\Common\Collections\ArrayCollection();
        $this->person = new \Doctrine\Common\Collections\ArrayCollection();
        $this->place = new \Doctrine\Common\Collections\ArrayCollection();
    }
    /**
     * Sets id.
     *
     * @param int $id
     *
     * @return $this
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }
    /**
     * Gets id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Get organization
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getOrganization()
    {
        return $this->organization;
    }
    /**
     * Get person
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getPerson()
    {
        return $this->person;
    }
    /**
     * Get place
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getPlace()
    {
        return $this->place;
    }
    /**
     * Sets contactType.
     *
     * @param string $contactType
     *
     * @return $this
     */
    public function setContactType($contactType)
    {
        $this->contactType = $contactType;

        return $this;
    }
    /**
     * Gets contactType.
     *
     * @return string
     */
    public function getContactType()
    {
        return $this->contactType;
    }
    /**
     * Sets email.
     *
     * @param string $email
     *
     * @return $this
     */
    public function setEmail($email)
    {
        $this->email = $email;

        if(!is_null($email) && !is_null($this->getEmailInvalid()))
            $this->setEmailInvalid(NULL);

        return $this;
    }
    /**
     * Gets email.
     *
     * @return string
     */
    public function getEmail()
    {
        return $this->email;
    }
    /**
     * Sets email Invalid.
     *
     * @param string $emailInvalid
     *
     * @return $this
     */
    public function setEmailInvalid($emailInvalid)
    {
        $this->emailInvalid = is_null($this->email) ? $emailInvalid : NULL;

        return $this;
    }
    /**
     * Gets email Invalid.
     *
     * @return string
     */
    public function getEmailInvalid()
    {
        return $this->emailInvalid;
    }
    /**
     * Sets faxNumber.
     *
     * @param string $faxNumber
     *
     * @return $this
     */
    public function setFaxNumber($faxNumber)
    {
        if(empty($faxNumber))$faxNumber = null;

        if(is_null($faxNumber)) $this->faxNumber = $faxNumber;
        else{
            $phoneUtil = PhoneNumberUtil::getInstance();
            $phoneNumber = $phoneUtil->parse($faxNumber, PhoneNumberUtil::UNKNOWN_REGION);
            $this->faxNumber = $phoneNumber;
        }

        if(!is_null($this->faxNumber) && !is_null($this->getFaxNumberInvalid()))
            $this->setFaxNumberInvalid(NULL);

        return $this;
    }
    /**
     * Gets faxNumber.
     *
     * @return string
     */
    public function getFaxNumber()
    {
        return $this->faxNumber;
    }
    /**
     * Sets faxNumber Invalid.
     *
     * @param string $faxNumberInvalid
     *
     * @return $this
     */
    public function setFaxNumberInvalid($faxNumberInvalid)
    {
        $this->faxNumberInvalid = is_null($this->faxNumber) ? $faxNumberInvalid : NULL;
        return $this;
    }
    /**
     * Gets faxNumber Invalid.
     *
     * @return string
     */
    public function getFaxNumberInvalid()
    {
        return $this->faxNumberInvalid;
    }
    /**
     * Sets telphone.
     *
     * @param string $telphone
     *
     * @return $this
     */
    public function setTelphone($telphone)
    {
        if(empty($telphone))$telphone = null;

        if(is_null($telphone)) $this->telphone = $telphone;
        else{
            $phoneUtil = PhoneNumberUtil::getInstance();
            $phoneNumber = $phoneUtil->parse($telphone, PhoneNumberUtil::UNKNOWN_REGION);
            $this->telphone = $phoneNumber;
        }

        if(!is_null($this->telphone) && !is_null($this->getTelphoneInvalid()))
            $this->setTelphoneInvalid(NULL);

        return $this;
    }
    public function setPhoneNumberTelphone(PhoneNumber $phoneNumberTelphone)
    {
        $this->telphone = $phoneNumberTelphone;
    }
    /**
     * Gets telphone.
     *
     * @return string
     */
    public function getTelphone()
    {
        return $this->telphone;
    }
    /**
     * Sets telphone Invalid.
     *
     * @param string $telphoneInvalid
     *
     * @return $this
     */
    public function setTelphoneInvalid($telphoneInvalid)
    {
        $this->telphoneInvalid = is_null($this->telphone) ? $telphoneInvalid : NULL;
        return $this;
    }
    /**
     * Gets telphone Invalid.
     *
     * @return string
     */
    public function getTelphoneInvalid()
    {
        return $this->telphoneInvalid;
    }
    /**
     * Sets mobilPhone.
     *
     * @param string $mobilPhone
     *
     * @return $this
     */
    public function setMobilPhone($mobilPhone)
    {
        if(empty($mobilPhone))$mobilPhone = null;

        if(is_null($mobilPhone)) $this->mobilPhone = $mobilPhone;
        else{
            $phoneUtil = PhoneNumberUtil::getInstance();
            $phoneNumber = $phoneUtil->parse($mobilPhone, PhoneNumberUtil::UNKNOWN_REGION);
            $this->mobilPhone = $phoneNumber;
        }

        if(!is_null($this->mobilPhone) && !is_null($this->getMobilPhoneInvalid()))
            $this->setMobilPhoneInvalid(NULL);

        return $this;
    }
    public function setPhoneNumberMobilPhone(PhoneNumber $phoneNumberMobilPhone){
        $this->mobilPhone = $phoneNumberMobilPhone;
    }
    /**
     * Gets mobilPhone.
     *
     * @return string
     */
    public function getMobilPhone()
    {
        return $this->mobilPhone;
    }
    /**
     * Sets mobilPhone Invalid .
     *
     * @param string $mobilPhoneInvalid
     *
     * @return $this
     */
    public function setMobilPhoneInvalid($mobilPhoneInvalid)
    {
        $this->mobilPhoneInvalid = is_null($this->mobilPhone) ? $mobilPhoneInvalid : NULL;
        return $this;
    }
    /**
     * Gets mobilPhone Invalid.
     *
     * @return string
     */
    public function getMobilPhoneInvalid()
    {
        return $this->mobilPhoneInvalid;
    }
    /**
     * Gets full label.
     *
     * @return array
     */
    public function getFullLabelTemplate()
    {
        return [
            $this->getEmail(),
            $this->getTelphoneTemplate()[0],
            $this->getMobilPhoneTemplate()[0]

        ];
    }
    /**
     * Gets full label.
     *
     * @return array
     */
    public function getTelphoneTemplate()
    {
        return [
            ['type' => 'phone_number', 'value' => $this->getTelphone(), 'separator' => ' / ']
        ];
    }
    /**
     * Gets full label.
     *
     * @return array
     */
    public function getMobilPhoneTemplate()
    {
        return [
            ['type' => 'phone_number', 'value' => $this->getMobilPhone(), 'separator' => ' / ']
        ];
    }
    /**
     * Add organization
     *
     * @param \AppBundle\Entity\Organization\Organization $organization
     *
     * @return ContactPoint
     */
    public function addOrganization(\AppBundle\Entity\Organization\Organization $organization)
    {
        $this->organization[] = $organization;

        return $this;
    }
    /**
     * Remove organization
     *
     * @param \AppBundle\Entity\Organization\Organization $organization
     */
    public function removeOrganization(\AppBundle\Entity\Organization\Organization $organization)
    {
        $this->organization->removeElement($organization);
    }
    /**
     * Add person
     *
     * @param \AppBundle\Entity\Person\Person $person
     *
     * @return ContactPoint
     */
    public function addPerson(\AppBundle\Entity\Person\Person $person)
    {
        $this->person[] = $person;

        return $this;
    }
    /**
     * Remove person
     *
     * @param \AppBundle\Entity\Person\Person $person
     */
    public function removePerson(\AppBundle\Entity\Person\Person $person)
    {
        $person->removeContactPoint($this);
        $this->person->removeElement($person);
    }
    /**
     * Add place
     *
     * @param \AppBundle\Entity\Place\Place $place
     *
     * @return ContactPoint
     */
    public function addPlace(\AppBundle\Entity\Place\Place $place)
    {
        $this->place[] = $place;

        return $this;
    }
    /**
     * Remove place
     *
     * @param \AppBundle\Entity\Place\Place $place
     */
    public function removePlace(\AppBundle\Entity\Place\Place $place)
    {
        $this->place->removeElement($place);
    }
    /**
     * Gets invalidReason.
     *
     * @return string
     */
    public function getInvalidReason()
    {
        return $this->invalidReason;
    }
    /**
     * Sets invalidReason
     *
     * @param string $invalidReason
     *
     * @return $this
     */
    public function setInvalidReason($invalidReason)
    {
        $this->invalidReason = $invalidReason;
        return $this;
    }
    /**
     * @return string
     */
    public function getInvalidStatus()
    {
        return $this->invalidStatus;
    }
    /**
     * @param string $invalidStatus
     */
    public function setInvalidStatus($invalidStatus)
    {
        $this->invalidStatus = $invalidStatus;
    }
    /**
     * Gets full label.
     *
     * @return array
     */
    public function getFullLabelPrincipalTemplate()
    {
        return $this->getFullLabelTemplateByType(ContactPointTypeEnum::PRINCIPAL);
    }
    /**
     * Gets full label.
     *
     * @return array
     */
    public function getFullLabelContactTemplate()
    {
        return $this->getFullLabelTemplateByType(ContactPointTypeEnum::CONTACT);
    }
    /**
     * Gets full label.
     *
     * @return string
     */
    public function getFullLabelBillTemplate()
    {
        return $this->getFullLabelTemplateByType(ContactPointTypeEnum::BILL);
    }
    /**
     * @param $contactPointTypeEnum
     * @return array
     */
    private function getFullLabelTemplateByType($contactPointTypeEnum)
    {
        $label = [];

        if($this->contactType === $contactPointTypeEnum){
            $label =  [
                $this->getEmail(),
                ['type' => 'phone_number', 'value' => $this->getTelphone()],
                ['type' => 'phone_number', 'value' => $this->getMobilPhone()]

            ];
        }

        return $label;
    }
    /**
     * @return string
     */
    public function getInvalidEmailBody()
    {
        return $this->invalidEmailBody;
    }
    /**
     * @param string $invalidEmailBody
     */
    public function setInvalidEmailBody($invalidEmailBody)
    {
        $this->invalidEmailBody = $invalidEmailBody;
    }
    /**
     * @return string
     */
    public function getInvalidCat()
    {
        return $this->invalidCat;
    }
    /**
     * @param string $invalidCat
     */
    public function setInvalidCat($invalidCat)
    {
        $this->invalidCat = $invalidCat;
    }
}
