<?php

namespace App\Entity\Properties;

use DateTimeInterface;
use App\Entity\Common\IdTrait;
use App\Entity\Properties\Bien;
use App\Entity\Common\SlugTrait;
use Doctrine\ORM\Mapping as ORM;
use App\Entity\Common\DatesTrait;
use App\Entity\Acteurs\Locataires;
use App\Entity\Common\ActiveTrait;
use App\Entity\Common\DeletedTrait;
use App\Entity\Acteurs\Proprietaires;
use App\Entity\Quittances\Quittances;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\Common\Collections\Collection;
use App\Entity\Parametres\Locations\Locations;
use Doctrine\Common\Collections\ArrayCollection;
use App\Repository\Properties\PropertiesRepository;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass=PropertiesRepository::class)
 * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false)
 */
class Properties
{
    use IdTrait;
    use DatesTrait;
    use SlugTrait;
    use DeletedTrait;
    use ActiveTrait;

    public const PROPERTIE_ADD_SUCCESSFULLY = 'PROPERTIE_ADD_SUCCESSFULLY';
    public const PROPERTIE_INVALID_FORM = 'PROPERTIE_INVALID_FORM';

    /**
     * @ORM\Column(type="string", length=15)
     */
    private string $code;

    /**
     * @ORM\Column(type="string", length=50, nullable=true)
     */
    private ?string $num_appartement = null;

    /**
     * @ORM\Column(type="integer", length=15)
     */
    private int $numero_facture;

    /**
     * @ORM\Column(type="string", length=100)
     * @Assert\NotBlank(message="Veuillez saisir le nom de la propriété svp!")
     * @Assert\Length(min= 5)
     */
    private ?string $name;

    /**
     * @ORM\Column(type="decimal", precision=10, scale=2, options={"default": 0.0})
     * @Assert\NotBlank(message="Veuillez saisir le montant du quittance svp!")
     */
    private float $montant_loyer = 0.0;

    /**
     * @ORM\Column(type="string", length=500, nullable=true)
     */
    private ?string $adresse = null;

    /**
     * @ORM\Column(type="string", length=100, nullable=true)
     */
    private ?string $caution_gestionnaire = null;

    /**
     * @ORM\Column(type="string", length=100, nullable=true)
     */
    private ?string $caution_libelle = null;

    /**
     * @ORM\Column(type="integer", nullable=true, options={"default": 0})
     */
    private ?int $caution_periode = 0;

    /**
     * @ORM\Column(type="integer", nullable=true, options={"default": 0})
     */
    private ?int $delais_loyer = 0;

    /**
     * @ORM\Column(type="integer", nullable=true, options={"default": 0})
     */
    private ?int $caution_mois = 0;

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    private ?int $companyId = null;

    /**
     * @ORM\Column(type="decimal", precision=10, scale=2, nullable=true, options={"default": null})
     */
    private ?float $caution_montant = null;

    /**
     * @ORM\Column(type="date", nullable=true)
     */
    private DateTimeInterface|null $caution_date = null;

    /**
     * @ORM\ManyToOne(targetEntity=Categories::class, inversedBy="properties")
     * @Assert\NotBlank(message="Veuillez sélectionner un type svp!")
     */
    private ?Categories $categories = null;

    /**
     * @ORM\ManyToOne(targetEntity=Locataires::class, inversedBy="properties")
     * @Assert\NotBlank(message="Veuillez sélectionner un locataire svp!")
     */
    private ?Locataires $locataires = null;

    /**
     * @ORM\ManyToOne(targetEntity=Proprietaires::class, inversedBy="properties")
     * @Assert\NotBlank(message="Veuillez sélectionner un propriétaire svp!")
     */
    private ?Proprietaires $proprietaires = null;

    /**
     * @ORM\ManyToMany(targetEntity=Documents::class, mappedBy="properties", cascade={"persist", "remove"})
     */
    private Collection $documents;

    /**
     * @ORM\OneToMany(targetEntity=Quittances::class, mappedBy="properties", cascade={"remove"})
     */
    private Collection $quittances;

    /**
     * @ORM\OneToMany(targetEntity=Chargescautions::class, mappedBy="properties", cascade={"persist", "remove"})
     */
    private Collection $chargescautions;

    /**
     * @ORM\ManyToOne(targetEntity=Locations::class, inversedBy="properties")
     */
    private ?Locations $locations = null;

    public function __construct()
    {
        $this->documents = new ArrayCollection();
        $this->quittances = new ArrayCollection();
        $this->chargescautions = new ArrayCollection();
    }

    public function getCode(): ?string
    {
        return $this->code;
    }

    public function setCode(string $code): self
    {
        $this->code = $code;

        return $this;
    }

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

    /**
     * @param string|null $num_appartement
     * @return Properties
     */
    public function setNumAppartement(?string $num_appartement): Properties
    {
        $this->num_appartement = $num_appartement;
        return $this;
    }

    public function getCompanyId(): ?int
    {
        return $this->companyId;
    }

    public function setCompanyId(?int $companyId): self
    {
        $this->companyId = $companyId;
        return $this;
    }


    /**
     * @return int|null
     */
    public function getNumeroFacture(): ?int
    {
        return $this->numero_facture;
    }

    /**
     * @param int $numero_facture
     * @return Properties
     */
    public function setNumeroFacture(int $numero_facture): Properties
    {
        $this->numero_facture = $numero_facture;
        return $this;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getMontantLoyer(): ?float
    {
        return (float) $this->montant_loyer;
    }

    public function setMontantLoyer(float $montant_loyer): self
    {
        $this->montant_loyer = $montant_loyer;

        return $this;
    }

    public function getAdresse(): ?string
    {
        return $this->adresse;
    }

    public function setAdresse(?string $adresse): self
    {
        $this->adresse = $adresse;

        return $this;
    }

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

    /**
     * @param string|null $caution_gestionnaire
     * @return Properties
     */
    public function setCautionGestionnaire(?string $caution_gestionnaire): Properties
    {
        $this->caution_gestionnaire = $caution_gestionnaire;
        return $this;
    }

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

    /**
     * @param string|null $caution_libelle
     * @return Properties
     */
    public function setCautionLibelle(?string $caution_libelle): Properties
    {
        $this->caution_libelle = $caution_libelle;
        return $this;
    }

    /**
     * @return int|null
     */
    public function getCautionPeriode(): ?int
    {
        return $this->caution_periode;
    }

    /**
     * @param int|null $caution_periode
     * @return Properties
     */
    public function setCautionPeriode(?int $caution_periode): Properties
    {
        $this->caution_periode = $caution_periode;
        return $this;
    }

    /**
     * @return int|null
     */
    public function getDelaisLoyer(): ?int
    {
        return $this->delais_loyer;
    }

    /**
     * @param int|null $delais_loyer
     * @return Properties
     */
    public function setDelaisLoyer(?int $delais_loyer): Properties
    {
        $this->delais_loyer = $delais_loyer;
        return $this;
    }

    /**
     * @return int|null
     */
    public function getCautionMois(): ?int
    {
        return $this->caution_mois;
    }

    /**
     * @param int|null $caution_mois
     * @return Properties
     */
    public function setCautionMois(?int $caution_mois): Properties
    {
        $this->caution_mois = $caution_mois;
        return $this;
    }

    /**
     * @return float|int|null
     */
    public function getCautionMontant(): float|int|null
    {
        return $this->caution_montant;
    }

    /**
     * @param float|int|null $caution_montant
     * @return Properties
     */
    public function setCautionMontant(float|int|null $caution_montant): Properties
    {
        $this->caution_montant = $caution_montant;
        return $this;
    }

    /**
     * @return DateTimeInterface|null
     */
    public function getCautionDate(): ?DateTimeInterface
    {
        return $this->caution_date;
    }

    /**
     * @param DateTimeInterface|null $caution_date
     * @return Properties
     */
    public function setCautionDate(?DateTimeInterface $caution_date): Properties
    {
        $this->caution_date = $caution_date;
        return $this;
    }

    public function getCategories(): ?Categories
    {
        return $this->categories;
    }

    public function setCategories(?Categories $categories): self
    {
        $this->categories = $categories;

        return $this;
    }

    public function __toString(): string
    {
        return $this->name;
    }

    public function getLocataires(): ?Locataires
    {
        return $this->locataires;
    }

    public function setLocataires(?Locataires $locataires): self
    {
        $this->locataires = $locataires;

        return $this;
    }

    public function getProprietaires(): ?Proprietaires
    {
        return $this->proprietaires;
    }

    public function setProprietaires(?Proprietaires $proprietaires): self
    {
        $this->proprietaires = $proprietaires;

        return $this;
    }

    /**
     * @return Collection
     */
    public function getDocuments(): Collection
    {
        return $this->documents;
    }

    public function addDocument(Documents $document): self
    {
        if (!$this->documents->contains($document)) {
            $this->documents[] = $document;
            $document->addProperty($this);
        }

        return $this;
    }

    public function removeDocument(Documents $document): self
    {
        if ($this->documents->removeElement($document)) {
            $document->removeProperty($this);
        }

        return $this;
    }

    /**
     * @return Collection
     */
    public function getQuittances(): Collection
    {
        return $this->quittances;
    }

    public function addLoyer(Quittances $quittance): self
    {
        if (!$this->quittances->contains($quittance)) {
            $this->quittances[] = $quittance;
            $quittance->setProperties($this);
        }

        return $this;
    }

    public function removeLoyer(Quittances $quittance): self
    {
        if ($this->quittances->removeElement($quittance)) {
            // set the owning side to null (unless already changed)
            if ($quittance->getProperties() === $this) {
                $quittance->setProperties(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection
     */
    public function getChargescautions(): Collection
    {
        return $this->chargescautions;
    }

    public function addChargescaution(Chargescautions $chargescaution): self
    {
        if (!$this->chargescautions->contains($chargescaution)) {
            $this->chargescautions[] = $chargescaution;
            $chargescaution->setProperties($this);
        }

        return $this;
    }

    public function removeChargescaution(Chargescautions $chargescaution): self
    {
        if ($this->chargescautions->removeElement($chargescaution)) {
            // set the owning side to null (unless already changed)
            if ($chargescaution->getProperties() === $this) {
                $chargescaution->setProperties(null);
            }
        }

        return $this;
    }

    public function getLocations(): ?Locations
    {
        return $this->locations;
    }

    public function setLocations(?Locations $locations): self
    {
        $this->locations = $locations;

        return $this;
    }



    /** AJOUT */

    /**
     * @ORM\ManyToOne(targetEntity=Bien::class, inversedBy="properties")
     */
    private ?Bien $bien = null;

    /**
     * @ORM\OneToMany(targetEntity=Charge::class, mappedBy="properties")
     */
    private Collection $charges;

    /**
     * @ORM\OneToMany(targetEntity=Commission::class, mappedBy="properties")
     */
    private Collection $commissions;


    public function getBien(): ?Bien
    {
        return $this->bien;
    }

    public function setBien(?Bien $bien): self
    {
        $this->bien = $bien;
        return $this;
    }

    // src/Entity/Properties/Properties.php
    public function getCommissionPourBien(): float
    {
        $commissionRate = $this->getBien()?->getProprietaire()?->getCommission() ?? 0;
        return $this->getMontantLoyer() * $commissionRate / 100;
    }
}
