<?php

declare (strict_types=1);

namespace App\Entity\Organization;

use ApiPlatform\Metadata\Put;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\ApiResource;
use App\Entity\Access\Access;
use App\Entity\Core\File;
use App\Repository\Organization\ParametersRepository;
use App\State\Processor\Organization\ParametersProcessor;

//use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use JetBrains\PhpStorm\Pure;
use Symfony\Component\Validator\Constraints as Assert;
use App\Validator\Organization\Parameters as OpentalentAssert;

#[ApiResource(
    operations: [
        new Get(
            security: '(is_granted("ROLE_ORGANIZATION_VIEW") or is_granted("ROLE_ORGANIZATION")) and object.getOrganization().getId() == user.getOrganization().getId()'
        ),
        new Put(
            security: 'is_granted("ROLE_ORGANIZATION") and object.getOrganization().getId() == user.getOrganization().getId()'
        )
    ],
    processor: ParametersProcessor::class
)]
//#[Auditable]
#[ORM\Entity(repositoryClass: ParametersRepository::class)]
#[OpentalentAssert\MobytCredentials]
class Parameters
{
    #[ORM\Id]
    #[ORM\Column]
    #[ORM\GeneratedValue]
    private ?int $id = null;

    #[ORM\OneToOne(mappedBy: 'parameters', targetEntity: Organization::class)]
    private Organization $organization;

    #[ORM\Column(type: 'date', nullable: true)]
    private ?\DateTimeInterface $financialDate = null;

    #[ORM\Column(type: 'date', nullable: true)]
    private ?\DateTimeInterface $musicalDate = null;

    #[ORM\Column(type: 'date', nullable: true)]
    private ?\DateTimeInterface $startCourseDate = null;

    #[ORM\Column(type: 'date', nullable: true)]
    private ?\DateTimeInterface $endCourseDate = null;

    #[ORM\Column(options: ['default' => 20])]
    #[Assert\Range(notInRangeMessage: 'between_{{ min }}_and_{{ max }}', min: 0, max: 100)]
    private int $average = 20;

    #[ORM\Column(options: ['default' => true])]
    private bool $editCriteriaNotationByAdminOnly = true;

    #[ORM\Column(length: 255, nullable: true)]
    #[Assert\Regex('/^[a-z0-9]+$/i', message: 'smsSenderName_error')]
    private ?string $smsSenderName = null;

    #[ORM\Column(options: ['default' => false])]
    private bool $logoDonorsMove = false;

    #[ORM\Column(length: 60, nullable: true)]
    private ?string $subDomain = null;

    #[ORM\Column(length: 100, nullable: true)]
    private ?string $website = null;

    #[ORM\Column(length: 150, nullable: true)]
    private ?string $otherWebsite = null;

    #[ORM\Column(length: 150, nullable: true)]
    private ?string $customDomain = null;

    #[ORM\Column(options: ['default' => false])]
    private bool $desactivateOpentalentSiteWeb = false;

    #[ORM\OneToMany(mappedBy: 'publicationDirector', targetEntity: Access::class)]
    private Collection $publicationDirectors;

    #[ORM\Column(length: 255, nullable: true)]
    #[Assert\Choice(callback: ['\\App\\Enum\\Organization\\BulletinPeriodEnum', 'toArray'], message: 'invalid-bulletin-period')]
    private ?string $bulletinPeriod = null;

    #[ORM\Column(options: ['default' => false])]
    private bool $bulletinWithTeacher = false;

    #[ORM\Column(options: ['default' => false])]
    private bool $bulletinPrintAddress = false;

    #[ORM\Column(options: ['default' => true])]
    private bool $bulletinSignatureDirector = true;

    #[ORM\Column(options: ['default' => true])]
    private bool $bulletinDisplayLevelAcquired = true;

    #[ORM\Column(options: ['default' => false])]
    private bool $bulletinShowEducationWithoutEvaluation = false;

    #[ORM\Column(options: ['default' => false])]
    private bool $bulletinViewTestResults = false;

    #[ORM\Column(options: ['default' => false])]
    private bool $bulletinShowAbsences = false;

    #[ORM\Column(options: ['default' => true])]
    private bool $bulletinShowAverages = true;

    #[ORM\Column(length: 255, nullable: true)]
    #[Assert\Choice(callback: ['\\App\\Enum\\Organization\\BulletinOutputEnum', 'toArray'], message: 'invalid-bulletin-output')]
    private ?string $bulletinOutput = null;

    #[ORM\Column(options: ['default' => true])]
    private bool $bulletinEditWithoutEvaluation = true;

    #[ORM\Column(length: 255, nullable: true, options: ['default' => 'STUDENTS_AND_THEIR_GUARDIANS'])]
    #[Assert\Choice(callback: ['\\App\\Enum\\Organization\\SendToBulletinEnum', 'toArray'], message: 'invalid-send-to-bulletin')]
    private ?string $bulletinReceiver = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $usernameSMS = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $passwordSMS = null;

    #[ORM\Column(options: ['default' => true])]
    private bool $showAdherentList = true;

    #[ORM\Column(options: ['default' => false])]
    private bool $studentsAreAdherents = false;

    #[ORM\OneToOne(inversedBy: 'qrCode', targetEntity: File::class, cascade: ['persist'], fetch: 'EAGER')]
    #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
    private ?File $qrCode = null;

    #[ORM\Column(length: 255, options: ['default' => 'Europe/Paris'])]
    #[Assert\Choice(callback: ['\\App\\Enum\\Core\\TimeZoneEnum', 'toArray'], message: 'invalid-timezone')]
    private ?string $timezone = "Europe/Paris";

    #[ORM\Column(length: 255, nullable: false, options: ['default' => 'ANNUAL'])]
    #[Assert\Choice(callback: ['\\App\\Enum\\Education\\PeriodicityEnum', 'toArray'], message: 'invalid-periodicity')]
    private ?string $educationPeriodicity = 'ANNUAL';

    #[ORM\Column(length: 255, nullable: true, options: ['default' => 'BY_EDUCATION'])]
    #[Assert\Choice(callback: ['\\App\\Enum\\Education\\AdvancedEducationNotationTypeEnum', 'toArray'], message: 'invalid-advanced-education-notation-type')]
    private ?string $advancedEducationNotationType = null;

    #[ORM\Column(options: ['default' => false])]
    private bool $sendAttendanceEmail = false;

    #[ORM\Column(options: ['default' => false])]
    private bool $sendAttendanceSms = false;

    #[Pure]
    public function __construct()
    {
        $this->publicationDirectors = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getOrganization(): Organization
    {
        return $this->organization;
    }

    public function setOrganization(Organization $organization): self
    {
        $this->organization = $organization;
        return $this;
    }

    public function getFinancialDate(): ?\DateTimeInterface
    {
        return $this->financialDate;
    }

    public function setFinancialDate(?\DateTimeInterface $financialDate): self
    {
        $this->financialDate = $financialDate;
        return $this;
    }

    public function getMusicalDate(): ?\DateTimeInterface
    {
        return $this->musicalDate;
    }

    public function setMusicalDate(?\DateTimeInterface $musicalDate): self
    {
        $this->musicalDate = $musicalDate;
        return $this;
    }

    public function getStartCourseDate(): ?\DateTimeInterface
    {
        return $this->startCourseDate;
    }

    public function setStartCourseDate(?\DateTimeInterface $startCourseDate): self
    {
        $this->startCourseDate = $startCourseDate;
        return $this;
    }

    public function getEndCourseDate(): ?\DateTimeInterface
    {
        return $this->endCourseDate;
    }

    public function setEndCourseDate(?\DateTimeInterface $endCourseDate): self
    {
        $this->endCourseDate = $endCourseDate;
        return $this;
    }

    public function getAverage(): int
    {
        return $this->average;
    }

    public function setAverage(int $average): self
    {
        $this->average = $average;
        return $this;
    }

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

    public function setEditCriteriaNotationByAdminOnly(bool $editCriteriaNotationByAdminOnly): self
    {
        $this->editCriteriaNotationByAdminOnly = $editCriteriaNotationByAdminOnly;
        return $this;
    }

    public function getSmsSenderName(): ?string
    {
        return $this->smsSenderName;
    }

    public function setSmsSenderName(?string $smsSenderName): self
    {
        $this->smsSenderName = $smsSenderName;
        return $this;
    }

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

    public function setLogoDonorsMove(bool $logoDonorsMove): self
    {
        $this->logoDonorsMove = $logoDonorsMove;
        return $this;
    }

    public function getOtherWebsite(): ?string
    {
        return $this->otherWebsite;
    }

    public function setOtherWebsite(?string $otherWebsite): self
    {
        $this->otherWebsite = $otherWebsite;
        return $this;
    }

    /**
     * @return string|null
     */
    public function getCustomDomain(): ?string
    {
        return $this->customDomain;
    }

    /**
     * @param string|null $customDomain
     */
    public function setCustomDomain(?string $customDomain): void
    {
        $this->customDomain = $customDomain;
    }

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

    public function setDesactivateOpentalentSiteWeb(bool $desactivateOpentalentSiteWeb): self
    {
        $this->desactivateOpentalentSiteWeb = $desactivateOpentalentSiteWeb;
        return $this;
    }

    public function getBulletinPeriod(): ?string
    {
        return $this->bulletinPeriod;
    }

    public function setBulletinPeriod(?string $bulletinPeriod): self
    {
        $this->bulletinPeriod = $bulletinPeriod;
        return $this;
    }

    public function getPublicationDirectors(): Collection
    {
        return $this->publicationDirectors;
    }

    public function addPublicationDirector(Access $access): self
    {
        if (!$this->publicationDirectors->contains($access)) {
            $this->publicationDirectors[] = $access;
            $access->setPublicationDirector($this);
        }
        return $this;
    }

    public function removePublicationDirector(Access $access): self
    {
        if ($this->publicationDirectors->removeElement($access)) {
            // set the owning side to null (unless already changed)
            if ($access->getPublicationDirector() === $this) {
                $access->setPublicationDirector(null);
            }
        }
        return $this;
    }

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

    public function setBulletinWithTeacher(bool $bulletinWithTeacher): self
    {
        $this->bulletinWithTeacher = $bulletinWithTeacher;
        return $this;
    }

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

    public function setBulletinPrintAddress(bool $bulletinPrintAddress): self
    {
        $this->bulletinPrintAddress = $bulletinPrintAddress;
        return $this;
    }

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

    public function setBulletinSignatureDirector(bool $bulletinSignatureDirector): self
    {
        $this->bulletinSignatureDirector = $bulletinSignatureDirector;
        return $this;
    }

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

    public function setBulletinDisplayLevelAcquired(bool $bulletinDisplayLevelAcquired): self
    {
        $this->bulletinDisplayLevelAcquired = $bulletinDisplayLevelAcquired;
        return $this;
    }

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

    public function setBulletinShowEducationWithoutEvaluation(bool $bulletinShowEducationWithoutEvaluation): self
    {
        $this->bulletinShowEducationWithoutEvaluation = $bulletinShowEducationWithoutEvaluation;
        return $this;
    }

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

    public function setBulletinViewTestResults(bool $bulletinViewTestResults): self
    {
        $this->bulletinViewTestResults = $bulletinViewTestResults;
        return $this;
    }

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

    public function setBulletinShowAbsences(bool $bulletinShowAbsences): self
    {
        $this->bulletinShowAbsences = $bulletinShowAbsences;
        return $this;
    }

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

    public function setBulletinShowAverages(bool $bulletinShowAverages): self
    {
        $this->bulletinShowAverages = $bulletinShowAverages;
        return $this;
    }

    public function getBulletinOutput(): ?string
    {
        return $this->bulletinOutput;
    }

    public function setBulletinOutput(?string $bulletinOutput): self
    {
        $this->bulletinOutput = $bulletinOutput;
        return $this;
    }

    public function getUsernameSMS(): ?string
    {
        return $this->usernameSMS;
    }

    public function setUsernameSMS(?string $usernameSMS): self
    {
        $this->usernameSMS = $usernameSMS;
        return $this;
    }

    public function getPasswordSMS(): ?string
    {
        return $this->passwordSMS;
    }

    public function setPasswordSMS(?string $passwordSMS): self
    {
        $this->passwordSMS = $passwordSMS;
        return $this;
    }

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

    public function setBulletinEditWithoutEvaluation(bool $bulletinEditWithoutEvaluation): self
    {
        $this->bulletinEditWithoutEvaluation = $bulletinEditWithoutEvaluation;
        return $this;
    }

    public function getBulletinReceiver(): ?string
    {
        return $this->bulletinReceiver;
    }

    public function setBulletinReceiver(?string $bulletinReceiver): self
    {
        $this->bulletinReceiver = $bulletinReceiver;
        return $this;
    }

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

    public function setShowAdherentList(bool $showAdherentList): self
    {
        $this->showAdherentList = $showAdherentList;
        return $this;
    }

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

    public function setStudentsAreAdherents(bool $studentsAreAdherents): self
    {
        $this->studentsAreAdherents = $studentsAreAdherents;
        return $this;
    }

    public function getTimezone(): string
    {
        return $this->timezone;
    }

    public function setTimezone(string $timezone): self
    {
        $this->timezone = $timezone;
        return $this;
    }

    public function getEducationPeriodicity(): ?string
    {
        return $this->educationPeriodicity;
    }

    public function setEducationPeriodicity(?string $educationPeriodicity): self
    {
        $this->educationPeriodicity = $educationPeriodicity;
        return $this;
    }

    public function getAdvancedEducationNotationType(): ?string
    {
        return $this->advancedEducationNotationType;
    }

    public function setAdvancedEducationNotationType(?string $advancedEducationNotationType): self
    {
        $this->advancedEducationNotationType = $advancedEducationNotationType;
        return $this;
    }

    public function getQrCode(): ?File
    {
        return $this->qrCode;
    }

    public function setQrCode(?File $qrCode): self
    {
        $this->qrCode = $qrCode;
        return $this;
    }

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

    public function setSendAttendanceSms(bool $sendAttendanceSms): self
    {
        $this->sendAttendanceSms = $sendAttendanceSms;
        return $this;
    }

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

    public function setSendAttendanceEmail(bool $sendAttendanceEmail): self
    {
        $this->sendAttendanceEmail = $sendAttendanceEmail;
        return $this;
    }
}
