<?php

declare(strict_types=1);

namespace App\Entity;

use App\Repository\MouvementCaisseRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: MouvementCaisseRepository::class)]
#[ORM\Table(name: 'mouvement_caisse')]
#[ORM\Index(name: 'IDX_MOUVEMENT_CAISSE_ECOLE_DATE', columns: ['ecole_id', 'date_mouvement', 'type'])]
#[ORM\HasLifecycleCallbacks]
class MouvementCaisse
{
    public const TYPE_ENTREE = 'ENTREE';
    public const TYPE_SORTIE = 'SORTIE';

    public const SOURCE_PAIEMENT = 'PAIEMENT';
    public const SOURCE_DEPENSE = 'DEPENSE';
    public const SOURCE_AJUSTEMENT = 'AJUSTEMENT';

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToOne]
    #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
    private ?Ecole $ecole = null;

    #[ORM\ManyToOne]
    #[ORM\JoinColumn(onDelete: 'SET NULL')]
    private ?AnneeScolaire $anneeScolaire = null;

    #[ORM\Column(length: 20)]
    private ?string $type = null;

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

    #[ORM\ManyToOne]
    #[ORM\JoinColumn(onDelete: 'SET NULL')]
    private ?Paiement $paiement = null;

    #[ORM\ManyToOne]
    #[ORM\JoinColumn(onDelete: 'SET NULL')]
    private ?Depense $depense = null;

    #[ORM\Column(type: Types::DECIMAL, precision: 12, scale: 2)]
    private ?string $montant = null;

    #[ORM\Column(type: Types::DATE_MUTABLE)]
    private ?\DateTimeInterface $dateMouvement = null;

    #[ORM\Column(length: 180)]
    private ?string $libelle = null;

    #[ORM\Column(type: Types::TEXT, nullable: true)]
    private ?string $observation = null;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
    private ?\DateTimeImmutable $createdAt = null;

    public function getId(): ?int { return $this->id; }
    public function getEcole(): ?Ecole { return $this->ecole; }
    public function setEcole(?Ecole $ecole): static { $this->ecole = $ecole; return $this; }
    public function getAnneeScolaire(): ?AnneeScolaire { return $this->anneeScolaire; }
    public function setAnneeScolaire(?AnneeScolaire $anneeScolaire): static { $this->anneeScolaire = $anneeScolaire; return $this; }
    public function getType(): ?string { return $this->type; }
    public function setType(string $type): static { $this->type = mb_strtoupper(trim($type)); return $this; }
    public function getSourceType(): ?string { return $this->sourceType; }
    public function setSourceType(?string $sourceType): static { $this->sourceType = $this->nullableUpper($sourceType); return $this; }
    public function getPaiement(): ?Paiement { return $this->paiement; }
    public function setPaiement(?Paiement $paiement): static { $this->paiement = $paiement; return $this; }
    public function getDepense(): ?Depense { return $this->depense; }
    public function setDepense(?Depense $depense): static { $this->depense = $depense; return $this; }
    public function getMontant(): ?string { return $this->montant; }
    public function setMontant(string|int|float $montant): static { $this->montant = (string) $montant; return $this; }
    public function getDateMouvement(): ?\DateTimeInterface { return $this->dateMouvement; }
    public function setDateMouvement(\DateTimeInterface $dateMouvement): static { $this->dateMouvement = \DateTime::createFromInterface($dateMouvement); return $this; }
    public function getLibelle(): ?string { return $this->libelle; }
    public function setLibelle(string $libelle): static { $this->libelle = trim($libelle); return $this; }
    public function getObservation(): ?string { return $this->observation; }
    public function setObservation(?string $observation): static { $this->observation = $this->nullableTrim($observation); return $this; }
    public function getCreatedAt(): ?\DateTimeImmutable { return $this->createdAt; }

    #[ORM\PrePersist]
    public function initializeCreatedAt(): void { $this->createdAt ??= new \DateTimeImmutable(); $this->dateMouvement ??= new \DateTimeImmutable(); }
    private function nullableTrim(?string $value): ?string { $value = $value !== null ? trim($value) : null; return $value !== '' ? $value : null; }
    private function nullableUpper(?string $value): ?string { $value = $this->nullableTrim($value); return $value !== null ? mb_strtoupper($value) : null; }
}
