<?php

declare(strict_types=1);

namespace App\Entity;

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

#[ORM\Entity(repositoryClass: EcheancePaiementRepository::class)]
#[ORM\Table(name: 'echeance_paiement')]
#[ORM\Index(name: 'IDX_ECHEANCE_STATUS', columns: ['ecole_id', 'annee_scolaire_id', 'statut', 'actif'])]
#[ORM\HasLifecycleCallbacks]
class EcheancePaiement
{
    public const STATUT_NON_PAYE = 'NON_PAYE';
    public const STATUT_PARTIEL = 'PARTIEL';
    public const STATUT_PAYE = 'PAYE';
    public const STATUT_EN_RETARD = 'EN_RETARD';
    public const STATUT_ANNULE = 'ANNULE';

    #[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(nullable: false, onDelete: 'CASCADE')]
    private ?Etudiant $etudiant = null;

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

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

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

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

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

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

    #[ORM\Column(type: Types::DECIMAL, precision: 12, scale: 2, options: ['default' => '0.00'])]
    private string $montantRemise = '0.00';

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

    #[ORM\Column(type: Types::DECIMAL, precision: 12, scale: 2, options: ['default' => '0.00'])]
    private string $montantPaye = '0.00';

    #[ORM\Column(type: Types::DATE_MUTABLE, nullable: true)]
    private ?\DateTimeInterface $dateEcheance = null;

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

    #[ORM\Column(length: 30, options: ['default' => self::STATUT_NON_PAYE])]
    private string $statut = self::STATUT_NON_PAYE;

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

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

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
    private ?\DateTimeImmutable $updatedAt = 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 getEtudiant(): ?Etudiant { return $this->etudiant; }
    public function setEtudiant(?Etudiant $etudiant): static { $this->etudiant = $etudiant; return $this; }
    public function getParcoursEtudiant(): ?ParcoursEtudiant { return $this->parcoursEtudiant; }
    public function setParcoursEtudiant(?ParcoursEtudiant $parcoursEtudiant): static { $this->parcoursEtudiant = $parcoursEtudiant; return $this; }
    public function getAnneeScolaire(): ?AnneeScolaire { return $this->anneeScolaire; }
    public function setAnneeScolaire(?AnneeScolaire $anneeScolaire): static { $this->anneeScolaire = $anneeScolaire; return $this; }
    public function getTypeFrais(): ?TypeFrais { return $this->typeFrais; }
    public function setTypeFrais(?TypeFrais $typeFrais): static { $this->typeFrais = $typeFrais; return $this; }
    public function getRegleFrais(): ?RegleFrais { return $this->regleFrais; }
    public function setRegleFrais(?RegleFrais $regleFrais): static { $this->regleFrais = $regleFrais; return $this; }
    public function getLibelle(): ?string { return $this->libelle; }
    public function setLibelle(string $libelle): static { $this->libelle = trim($libelle); return $this; }
    public function getMontantDu(): ?string { return $this->montantDu; }
    public function setMontantDu(string|int|float $montantDu): static { $this->montantDu = (string) $montantDu; return $this; }
    public function getMontantRemise(): string { return $this->montantRemise; }
    public function setMontantRemise(string|int|float $montantRemise): static { $this->montantRemise = (string) $montantRemise; return $this; }
    public function getMontantNet(): ?string { return $this->montantNet; }
    public function setMontantNet(string|int|float $montantNet): static { $this->montantNet = (string) $montantNet; return $this; }
    public function getMontantPaye(): string { return $this->montantPaye; }
    public function setMontantPaye(string|int|float $montantPaye): static { $this->montantPaye = (string) $montantPaye; return $this; }
    public function getDateEcheance(): ?\DateTimeInterface { return $this->dateEcheance; }
    public function setDateEcheance(?\DateTimeInterface $dateEcheance): static { $this->dateEcheance = $dateEcheance ? \DateTime::createFromInterface($dateEcheance) : null; return $this; }
    public function getPeriode(): ?string { return $this->periode; }
    public function setPeriode(?string $periode): static { $this->periode = $this->nullableTrim($periode); return $this; }
    public function getStatut(): string { return $this->statut; }
    public function setStatut(string $statut): static { $this->statut = mb_strtoupper(trim($statut)); return $this; }
    public function isActif(): bool { return $this->actif; }
    public function setActif(bool $actif): static { $this->actif = $actif; return $this; }
    public function getCreatedAt(): ?\DateTimeImmutable { return $this->createdAt; }
    public function getUpdatedAt(): ?\DateTimeImmutable { return $this->updatedAt; }

    #[ORM\PrePersist]
    public function initializeTimestamps(): void { $now = new \DateTimeImmutable(); $this->createdAt ??= $now; $this->updatedAt = $now; }
    #[ORM\PreUpdate]
    public function refreshUpdatedAt(): void { $this->updatedAt = new \DateTimeImmutable(); }
    private function nullableTrim(?string $value): ?string { $value = $value !== null ? trim($value) : null; return $value !== '' ? $value : null; }
}
