<?php

declare(strict_types=1);

namespace App\Entity;

use App\Enum\LeaveRuleCode;
use App\Repository\EmployeeLeaveBalanceRepository;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: EmployeeLeaveBalanceRepository::class)]
#[ORM\Table(name: 'employee_leave_balances', options: ['comment' => 'Soldes de conges par employe et exercice (ouverture, mouvements, cloture).'])]
#[ORM\UniqueConstraint(name: 'uniq_employee_leave_balance', columns: ['employee_id', 'rule_code', 'year'])]
#[ORM\Index(columns: ['employee_id', 'year'], name: 'idx_leave_balance_employee_year')]
class EmployeeLeaveBalance
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

    #[ORM\ManyToOne(targetEntity: Employee::class)]
    #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
    private ?Employee $employee = null;

    #[ORM\Column(length: 64, options: ['comment' => 'Code de regle de calcul des conges (CDI_CDD_NON_FORFAIT, FORFAIT_218, ...).'])]
    private string $ruleCode = '';

    #[ORM\Column(type: 'integer', options: ['comment' => 'Annee d exercice de reference (ex: 2026).'])]
    private int $year = 0;

    #[ORM\Column(type: 'float', options: ['comment' => 'Report N-1 en jours a l ouverture de l exercice.'])]
    private float $openingDays = 0.0;

    #[ORM\Column(type: 'float', options: ['comment' => 'Report N-1 en samedis a l ouverture (0 pour forfait).'])]
    private float $openingSaturdays = 0.0;

    #[ORM\Column(type: 'float', options: ['comment' => 'Droits jours acquis sur l exercice courant.'])]
    private float $accruedDays = 0.0;

    #[ORM\Column(type: 'float', options: ['comment' => 'Droits samedis acquis sur l exercice courant.'])]
    private float $accruedSaturdays = 0.0;

    #[ORM\Column(type: 'float', options: ['comment' => 'Jours de conges consommes sur l exercice.'])]
    private float $takenDays = 0.0;

    #[ORM\Column(type: 'float', options: ['comment' => 'Samedis consommes sur l exercice.'])]
    private float $takenSaturdays = 0.0;

    #[ORM\Column(type: 'float', options: ['comment' => 'Solde de cloture jours sur l exercice.'])]
    private float $closingDays = 0.0;

    #[ORM\Column(type: 'float', options: ['comment' => 'Solde de cloture samedis sur l exercice.'])]
    private float $closingSaturdays = 0.0;

    #[ORM\Column(type: 'float', options: ['default' => 0, 'comment' => 'Jours de fractionnement saisis par la RH.'])]
    private float $fractionedDays = 0.0;

    #[ORM\Column(type: 'float', options: ['default' => 0, 'comment' => 'Jours de conges N-1 payes par la RH (forfait uniquement).'])]
    private float $paidLeaveDays = 0.0;

    #[ORM\Column(type: 'boolean', options: ['default' => false, 'comment' => 'Indique si le solde de l exercice est fige (verrouille RH).'])]
    private bool $isLocked = false;

    #[ORM\Column(type: 'datetime_immutable')]
    private DateTimeImmutable $createdAt;

    #[ORM\Column(type: 'datetime_immutable')]
    private DateTimeImmutable $updatedAt;

    public function __construct()
    {
        $now             = new DateTimeImmutable();
        $this->createdAt = $now;
        $this->updatedAt = $now;
    }

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

    public function getEmployee(): ?Employee
    {
        return $this->employee;
    }

    public function setEmployee(Employee $employee): self
    {
        $this->employee = $employee;

        return $this;
    }

    public function getRuleCode(): string
    {
        return $this->ruleCode;
    }

    public function setRuleCode(LeaveRuleCode|string $ruleCode): self
    {
        $this->ruleCode = $ruleCode instanceof LeaveRuleCode ? $ruleCode->value : $ruleCode;

        return $this;
    }

    public function getYear(): int
    {
        return $this->year;
    }

    public function setYear(int $year): self
    {
        $this->year = $year;

        return $this;
    }

    public function getOpeningDays(): float
    {
        return $this->openingDays;
    }

    public function setOpeningDays(float $openingDays): self
    {
        $this->openingDays = $openingDays;

        return $this;
    }

    public function getOpeningSaturdays(): float
    {
        return $this->openingSaturdays;
    }

    public function setOpeningSaturdays(float $openingSaturdays): self
    {
        $this->openingSaturdays = $openingSaturdays;

        return $this;
    }

    public function getAccruedDays(): float
    {
        return $this->accruedDays;
    }

    public function setAccruedDays(float $accruedDays): self
    {
        $this->accruedDays = $accruedDays;

        return $this;
    }

    public function getAccruedSaturdays(): float
    {
        return $this->accruedSaturdays;
    }

    public function setAccruedSaturdays(float $accruedSaturdays): self
    {
        $this->accruedSaturdays = $accruedSaturdays;

        return $this;
    }

    public function getTakenDays(): float
    {
        return $this->takenDays;
    }

    public function setTakenDays(float $takenDays): self
    {
        $this->takenDays = $takenDays;

        return $this;
    }

    public function getTakenSaturdays(): float
    {
        return $this->takenSaturdays;
    }

    public function setTakenSaturdays(float $takenSaturdays): self
    {
        $this->takenSaturdays = $takenSaturdays;

        return $this;
    }

    public function getClosingDays(): float
    {
        return $this->closingDays;
    }

    public function setClosingDays(float $closingDays): self
    {
        $this->closingDays = $closingDays;

        return $this;
    }

    public function getClosingSaturdays(): float
    {
        return $this->closingSaturdays;
    }

    public function setClosingSaturdays(float $closingSaturdays): self
    {
        $this->closingSaturdays = $closingSaturdays;

        return $this;
    }

    public function getFractionedDays(): float
    {
        return $this->fractionedDays;
    }

    public function setFractionedDays(float $fractionedDays): self
    {
        $this->fractionedDays = $fractionedDays;

        return $this;
    }

    public function getPaidLeaveDays(): float
    {
        return $this->paidLeaveDays;
    }

    public function setPaidLeaveDays(float $paidLeaveDays): self
    {
        $this->paidLeaveDays = $paidLeaveDays;

        return $this;
    }

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

    public function setIsLocked(bool $isLocked): self
    {
        $this->isLocked = $isLocked;

        return $this;
    }

    public function getCreatedAt(): DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function getUpdatedAt(): DateTimeImmutable
    {
        return $this->updatedAt;
    }

    public function touch(): self
    {
        $this->updatedAt = new DateTimeImmutable();

        return $this;
    }
}
