<?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\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Repository\EmployeeWeekCommentRepository;
use App\State\EmployeeWeekCommentWriteProcessor;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
use Symfony\Component\Validator\Constraints as Assert;

#[ApiResource(
    operations: [
        new Get(security: "is_granted('ROLE_ADMIN')"),
        new GetCollection(security: "is_granted('ROLE_ADMIN')"),
        new Post(security: "is_granted('ROLE_ADMIN')", processor: EmployeeWeekCommentWriteProcessor::class),
        new Patch(security: "is_granted('ROLE_ADMIN')", processor: EmployeeWeekCommentWriteProcessor::class),
        new Delete(security: "is_granted('ROLE_ADMIN')", processor: EmployeeWeekCommentWriteProcessor::class),
    ],
    normalizationContext: ['groups' => ['week_comment:read'], 'datetime_format' => 'Y-m-d'],
    denormalizationContext: ['groups' => ['week_comment:write'], 'datetime_format' => 'Y-m-d'],
    order: ['weekStartDate' => 'DESC'],
    paginationEnabled: false,
)]
#[ApiFilter(DateFilter::class, properties: ['weekStartDate'])]
#[ApiFilter(SearchFilter::class, properties: ['employee' => 'exact'])]
#[ORM\Entity(repositoryClass: EmployeeWeekCommentRepository::class)]
#[ORM\Table(name: 'employee_week_comments')]
#[ORM\UniqueConstraint(name: 'uniq_employee_week_comment', columns: ['employee_id', 'week_start_date'])]
class EmployeeWeekComment
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    #[Groups(['week_comment:read'])]
    private ?int $id = null;

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

    #[ORM\Column(type: 'date_immutable')]
    #[Groups(['week_comment:read', 'week_comment:write'])]
    #[Assert\NotNull]
    private ?DateTimeImmutable $weekStartDate = null;

    #[ORM\Column(type: 'text')]
    #[Groups(['week_comment:read', 'week_comment:write'])]
    #[Assert\NotBlank]
    #[Assert\Length(max: 5000)]
    private string $content = '';

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

    #[ORM\Column(type: 'datetime_immutable')]
    #[Groups(['week_comment:read'])]
    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 getWeekStartDate(): ?DateTimeImmutable
    {
        return $this->weekStartDate;
    }

    public function setWeekStartDate(?DateTimeImmutable $weekStartDate): self
    {
        $this->weekStartDate = $weekStartDate;

        return $this;
    }

    public function getContent(): string
    {
        return $this->content;
    }

    public function setContent(string $content): self
    {
        $this->content = $content;

        return $this;
    }

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

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

    public function touchUpdatedAt(): void
    {
        $this->updatedAt = new DateTimeImmutable();
    }
}
