<?php

declare(strict_types=1);

namespace App\Entity;

use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
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 App\Entity\Trait\CuidEntityTrait;
use DateTimeImmutable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: 'comments')]
#[ORM\Index(columns: ['entity_type', 'entity_id', 'status'], name: 'idx_comment_entity_status')]
#[ORM\HasLifecycleCallbacks]
#[ApiFilter(SearchFilter::class, properties: ['entityType' => 'exact', 'entityId' => 'exact', 'status' => 'exact', 'entityName' => 'ipartial'])]
#[ApiFilter(OrderFilter::class, properties: ['createdAt', 'authorName', 'status'])]
#[ApiResource(
    description: 'Commentaires et annotations. Permet aux utilisateurs de commenter les machines, pièces, composants, produits et catégories. Les commentaires peuvent être marqués comme résolus.',
    operations: [
        new Get(security: "is_granted('ROLE_VIEWER')"),
        new GetCollection(security: "is_granted('ROLE_VIEWER')"),
        new Patch(security: "is_granted('ROLE_GESTIONNAIRE')"),
        new Delete(security: "is_granted('ROLE_GESTIONNAIRE')"),
    ],
    order: ['createdAt' => 'DESC'],
    paginationClientItemsPerPage: true,
    paginationMaximumItemsPerPage: 200
)]
class Comment
{
    use CuidEntityTrait;

    #[ORM\Id]
    #[ORM\Column(type: Types::STRING, length: 36)]
    private ?string $id = null;

    #[ORM\Column(type: Types::TEXT)]
    private string $content;

    #[ORM\Column(type: Types::STRING, length: 50, name: 'entity_type')]
    private string $entityType;

    #[ORM\Column(type: Types::STRING, length: 36, name: 'entity_id')]
    private string $entityId;

    #[ORM\Column(type: Types::STRING, length: 255, nullable: true, name: 'entity_name')]
    private ?string $entityName = null;

    #[ORM\Column(type: Types::STRING, length: 36, name: 'author_id')]
    private string $authorId;

    #[ORM\Column(type: Types::STRING, length: 255, name: 'author_name')]
    private string $authorName;

    #[ORM\Column(type: Types::STRING, length: 20)]
    private string $status = 'open';

    #[ORM\Column(type: Types::STRING, length: 36, nullable: true, name: 'resolved_by_id')]
    private ?string $resolvedById = null;

    #[ORM\Column(type: Types::STRING, length: 255, nullable: true, name: 'resolved_by_name')]
    private ?string $resolvedByName = null;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true, name: 'resolved_at')]
    private ?DateTimeImmutable $resolvedAt = null;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'created_at')]
    private DateTimeImmutable $createdAt;

    #[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'updated_at')]
    private DateTimeImmutable $updatedAt;

    /** @var Collection<int, Document> */
    #[ORM\OneToMany(targetEntity: Document::class, mappedBy: 'comment', cascade: ['remove'])]
    private Collection $documents;

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

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

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

        return $this;
    }

    public function getEntityType(): string
    {
        return $this->entityType;
    }

    public function setEntityType(string $entityType): static
    {
        $this->entityType = $entityType;

        return $this;
    }

    public function getEntityId(): string
    {
        return $this->entityId;
    }

    public function setEntityId(string $entityId): static
    {
        $this->entityId = $entityId;

        return $this;
    }

    public function getEntityName(): ?string
    {
        return $this->entityName;
    }

    public function setEntityName(?string $entityName): static
    {
        $this->entityName = $entityName;

        return $this;
    }

    public function getAuthorId(): string
    {
        return $this->authorId;
    }

    public function setAuthorId(string $authorId): static
    {
        $this->authorId = $authorId;

        return $this;
    }

    public function getAuthorName(): string
    {
        return $this->authorName;
    }

    public function setAuthorName(string $authorName): static
    {
        $this->authorName = $authorName;

        return $this;
    }

    public function getStatus(): string
    {
        return $this->status;
    }

    public function setStatus(string $status): static
    {
        $this->status = $status;

        return $this;
    }

    public function getResolvedById(): ?string
    {
        return $this->resolvedById;
    }

    public function setResolvedById(?string $resolvedById): static
    {
        $this->resolvedById = $resolvedById;

        return $this;
    }

    public function getResolvedByName(): ?string
    {
        return $this->resolvedByName;
    }

    public function setResolvedByName(?string $resolvedByName): static
    {
        $this->resolvedByName = $resolvedByName;

        return $this;
    }

    public function getResolvedAt(): ?DateTimeImmutable
    {
        return $this->resolvedAt;
    }

    public function setResolvedAt(?DateTimeImmutable $resolvedAt): static
    {
        $this->resolvedAt = $resolvedAt;

        return $this;
    }

    /** @return Collection<int, Document> */
    public function getDocuments(): Collection
    {
        return $this->documents;
    }
}
