<?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\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use App\Repository\WorkHourRepository;
use App\State\WorkHourSiteValidationProcessor;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;

#[ApiResource(
    operations: [
        new GetCollection(
            paginationEnabled: false,
            normalizationContext: ['groups' => ['work_hour:read', 'employee:read', 'site:read']],
            security: "is_granted('ROLE_USER')"
        ),
        new Get(
            normalizationContext: ['groups' => ['work_hour:read', 'employee:read', 'site:read']],
            security: "is_granted('WORK_HOUR_VIEW', object)"
        ),
        new Patch(
            normalizationContext: ['groups' => ['work_hour:read', 'employee:read', 'site:read']],
            denormalizationContext: ['groups' => ['work_hour:validate']],
            security: "is_granted('ROLE_ADMIN')"
        ),
        new Patch(
            uriTemplate: '/work_hours/{id}/site-validation',
            normalizationContext: ['groups' => ['work_hour:read', 'employee:read', 'site:read']],
            denormalizationContext: ['groups' => ['work_hour:site_validate']],
            security: "is_granted('ROLE_USER')",
            processor: WorkHourSiteValidationProcessor::class
        ),
    ],
)]
#[ApiFilter(DateFilter::class, properties: ['workDate'])]
#[ApiFilter(SearchFilter::class, properties: ['employee' => 'exact', 'employee.site' => 'exact'])]
#[ORM\Entity(repositoryClass: WorkHourRepository::class)]
#[ORM\Table(name: 'work_hours')]
#[ORM\UniqueConstraint(name: 'uniq_work_hours_employee_date', fields: ['employee', 'workDate'])]
class WorkHour
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    #[Groups(['work_hour:read'])]
    private ?int $id = null;

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

    #[ORM\Column(type: 'date_immutable')]
    #[Groups(['work_hour:read'])]
    private DateTimeInterface $workDate;

    #[ORM\Column(type: 'string', length: 5, nullable: true)]
    #[Groups(['work_hour:read'])]
    private ?string $morningFrom = null;

    #[ORM\Column(type: 'string', length: 5, nullable: true)]
    #[Groups(['work_hour:read'])]
    private ?string $morningTo = null;

    #[ORM\Column(type: 'string', length: 5, nullable: true)]
    #[Groups(['work_hour:read'])]
    private ?string $afternoonFrom = null;

    #[ORM\Column(type: 'string', length: 5, nullable: true)]
    #[Groups(['work_hour:read'])]
    private ?string $afternoonTo = null;

    #[ORM\Column(type: 'string', length: 5, nullable: true)]
    #[Groups(['work_hour:read'])]
    private ?string $eveningFrom = null;

    #[ORM\Column(type: 'string', length: 5, nullable: true)]
    #[Groups(['work_hour:read'])]
    private ?string $eveningTo = null;

    #[ORM\Column(type: 'boolean', options: ['default' => false])]
    #[Groups(['work_hour:read'])]
    private bool $isPresentMorning = false;

    #[ORM\Column(type: 'boolean', options: ['default' => false])]
    #[Groups(['work_hour:read'])]
    private bool $isPresentAfternoon = false;

    #[ORM\Column(type: 'integer', nullable: true)]
    #[Groups(['work_hour:read'])]
    private ?int $dayHoursMinutes = null;

    #[ORM\Column(type: 'integer', nullable: true)]
    #[Groups(['work_hour:read'])]
    private ?int $nightHoursMinutes = null;

    #[ORM\Column(type: 'integer', nullable: true)]
    #[Groups(['work_hour:read'])]
    private ?int $workshopHoursMinutes = null;

    #[ORM\Column(type: 'boolean', options: ['default' => false])]
    #[Groups(['work_hour:read'])]
    private bool $hasBreakfast = false;

    #[ORM\Column(type: 'boolean', options: ['default' => false])]
    #[Groups(['work_hour:read'])]
    private bool $hasLunch = false;

    #[ORM\Column(type: 'boolean', options: ['default' => false])]
    #[Groups(['work_hour:read'])]
    private bool $hasDinner = false;

    #[ORM\Column(type: 'boolean', options: ['default' => false])]
    #[Groups(['work_hour:read'])]
    private bool $hasOvernight = false;

    #[ORM\Column(type: 'boolean', options: ['default' => false])]
    #[Groups(['work_hour:read', 'work_hour:validate'])]
    private bool $isValid = false;

    #[ORM\Column(type: 'boolean', options: ['default' => false])]
    #[Groups(['work_hour:read', 'work_hour:site_validate'])]
    private bool $isSiteValid = false;

    #[ORM\Column(type: 'datetime_immutable', nullable: true)]
    #[Groups(['work_hour:read'])]
    private ?DateTimeImmutable $updatedAt = 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 getWorkDate(): DateTimeInterface
    {
        return $this->workDate;
    }

    public function setWorkDate(DateTimeInterface $workDate): self
    {
        $this->workDate = $workDate;

        return $this;
    }

    public function getMorningFrom(): ?string
    {
        return $this->morningFrom;
    }

    public function setMorningFrom(?string $morningFrom): self
    {
        $this->morningFrom = $morningFrom;

        return $this;
    }

    public function getMorningTo(): ?string
    {
        return $this->morningTo;
    }

    public function setMorningTo(?string $morningTo): self
    {
        $this->morningTo = $morningTo;

        return $this;
    }

    public function getAfternoonFrom(): ?string
    {
        return $this->afternoonFrom;
    }

    public function setAfternoonFrom(?string $afternoonFrom): self
    {
        $this->afternoonFrom = $afternoonFrom;

        return $this;
    }

    public function getAfternoonTo(): ?string
    {
        return $this->afternoonTo;
    }

    public function setAfternoonTo(?string $afternoonTo): self
    {
        $this->afternoonTo = $afternoonTo;

        return $this;
    }

    public function getEveningFrom(): ?string
    {
        return $this->eveningFrom;
    }

    public function setEveningFrom(?string $eveningFrom): self
    {
        $this->eveningFrom = $eveningFrom;

        return $this;
    }

    public function getEveningTo(): ?string
    {
        return $this->eveningTo;
    }

    public function setEveningTo(?string $eveningTo): self
    {
        $this->eveningTo = $eveningTo;

        return $this;
    }

    public function getDayHoursMinutes(): ?int
    {
        return $this->dayHoursMinutes;
    }

    public function setDayHoursMinutes(?int $dayHoursMinutes): self
    {
        $this->dayHoursMinutes = $dayHoursMinutes;

        return $this;
    }

    public function getNightHoursMinutes(): ?int
    {
        return $this->nightHoursMinutes;
    }

    public function setNightHoursMinutes(?int $nightHoursMinutes): self
    {
        $this->nightHoursMinutes = $nightHoursMinutes;

        return $this;
    }

    public function getWorkshopHoursMinutes(): ?int
    {
        return $this->workshopHoursMinutes;
    }

    public function setWorkshopHoursMinutes(?int $workshopHoursMinutes): self
    {
        $this->workshopHoursMinutes = $workshopHoursMinutes;

        return $this;
    }

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

    public function setHasBreakfast(bool $hasBreakfast): self
    {
        $this->hasBreakfast = $hasBreakfast;

        return $this;
    }

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

    public function setHasLunch(bool $hasLunch): self
    {
        $this->hasLunch = $hasLunch;

        return $this;
    }

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

    public function setHasDinner(bool $hasDinner): self
    {
        $this->hasDinner = $hasDinner;

        return $this;
    }

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

    public function setHasOvernight(bool $hasOvernight): self
    {
        $this->hasOvernight = $hasOvernight;

        return $this;
    }

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

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

    public function setIsPresentMorning(bool $isPresentMorning): self
    {
        $this->isPresentMorning = $isPresentMorning;

        return $this;
    }

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

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

    public function setIsPresentAfternoon(bool $isPresentAfternoon): self
    {
        $this->isPresentAfternoon = $isPresentAfternoon;

        return $this;
    }

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

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

    public function setIsValid(bool $isValid): self
    {
        $this->isValid = $isValid;

        return $this;
    }

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

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

    public function setIsSiteValid(bool $isSiteValid): self
    {
        $this->isSiteValid = $isSiteValid;

        return $this;
    }

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

    public function setUpdatedAt(?DateTimeImmutable $updatedAt): self
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }
}
