<?php

declare(strict_types=1);

namespace App\Entity;

use ApiPlatform\Doctrine\Orm\Filter\DateFilter;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Enum\HalfDay;
use App\Repository\AbsenceRepository;
use App\State\AbsenceWriteProcessor;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;

#[ApiResource(
    operations: [
        new GetCollection(
            security: "is_granted('ROLE_USER')"
        ),
        new Get(
            security: "is_granted('ABSENCE_VIEW', object)"
        ),
        new Post(
            securityPostDenormalize: "is_granted('ABSENCE_EDIT', object)",
            processor: AbsenceWriteProcessor::class
        ),
        new Patch(
            security: "is_granted('ABSENCE_EDIT', object)",
            processor: AbsenceWriteProcessor::class
        ),
        new Delete(
            security: "is_granted('ABSENCE_EDIT', object)",
            processor: AbsenceWriteProcessor::class
        ),
    ],
    normalizationContext: [
        'groups'          => ['absence:read', 'employee:read', 'absence_type:read'],
        'datetime_format' => 'Y-m-d',
    ],
    denormalizationContext: [
        'datetime_format' => 'Y-m-d',
    ],
    paginationEnabled: false,
)]
#[ApiFilter(DateFilter::class, properties: ['startDate', 'endDate'])]
#[ApiFilter(SearchFilter::class, properties: ['employee' => 'exact', 'employee.site' => 'exact'])]
#[ORM\Entity(repositoryClass: AbsenceRepository::class)]
#[ORM\Table(name: 'absences')]
class Absence
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    #[Groups(['absence:read'])]
    private ?int $id = null;

    #[ApiProperty(readableLink: true)]
    #[ORM\ManyToOne(targetEntity: Employee::class)]
    #[ORM\JoinColumn(nullable: false)]
    #[Groups(['absence:read'])]
    private ?Employee $employee = null;

    #[ApiProperty(readableLink: true)]
    #[ORM\ManyToOne(targetEntity: AbsenceType::class)]
    #[ORM\JoinColumn(nullable: false)]
    #[Groups(['absence:read'])]
    private ?AbsenceType $type = null;

    #[ORM\Column(type: 'date')]
    #[Groups(['absence:read'])]
    private DateTimeInterface $startDate;

    #[ORM\Column(type: 'string', length: 2, enumType: HalfDay::class, options: ['default' => 'AM'])]
    #[Groups(['absence:read'])]
    private HalfDay $startHalf = HalfDay::AM;

    #[ORM\Column(type: 'date')]
    #[Groups(['absence:read'])]
    private DateTimeInterface $endDate;

    #[ORM\Column(type: 'string', length: 2, enumType: HalfDay::class, options: ['default' => 'PM'])]
    #[Groups(['absence:read'])]
    private HalfDay $endHalf = HalfDay::PM;

    #[ORM\Column(type: 'text', nullable: true)]
    #[Groups(['absence:read'])]
    private ?string $comment = null;

    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 getType(): ?AbsenceType
    {
        return $this->type;
    }

    public function setType(?AbsenceType $type): self
    {
        $this->type = $type;

        return $this;
    }

    public function getStartDate(): DateTimeInterface
    {
        return $this->startDate;
    }

    public function setStartDate(DateTimeInterface $startDate): self
    {
        $this->startDate = $startDate;

        return $this;
    }

    public function getEndDate(): DateTimeInterface
    {
        return $this->endDate;
    }

    public function setEndDate(DateTimeInterface $endDate): self
    {
        $this->endDate = $endDate;

        return $this;
    }

    public function getStartHalf(): HalfDay
    {
        return $this->startHalf;
    }

    public function setStartHalf(HalfDay $startHalf): self
    {
        $this->startHalf = $startHalf;

        return $this;
    }

    public function getEndHalf(): HalfDay
    {
        return $this->endHalf;
    }

    public function setEndHalf(HalfDay $endHalf): self
    {
        $this->endHalf = $endHalf;

        return $this;
    }

    public function getComment(): ?string
    {
        return $this->comment;
    }

    public function setComment(?string $comment): self
    {
        $this->comment = $comment;

        return $this;
    }
}
