<?php

declare(strict_types=1);

namespace App\Module\Directory\Domain\Entity;

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\Post;
use App\Module\Directory\Infrastructure\ApiPlatform\State\ReportDocumentProcessor;
use App\Module\Directory\Infrastructure\EventListener\ReportDocumentListener;
use App\Shared\Domain\Contract\UserInterface;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;

#[ApiResource(
    operations: [
        new GetCollection(paginationEnabled: false, security: "is_granted('directory.clients.view') or is_granted('directory.prospects.view')"),
        new Get(security: "is_granted('directory.clients.view') or is_granted('directory.prospects.view')"),
        new Post(
            security: "is_granted('directory.clients.manage') or is_granted('directory.prospects.manage')",
            processor: ReportDocumentProcessor::class,
            deserialize: false,
        ),
        new Delete(security: "is_granted('directory.clients.manage') or is_granted('directory.prospects.manage')"),
    ],
    normalizationContext: ['groups' => ['report_document:read']],
    denormalizationContext: ['groups' => ['report_document:write']],
    order: ['id' => 'DESC'],
)]
#[ApiFilter(SearchFilter::class, properties: ['commercialReport' => 'exact'])]
#[ORM\Entity]
#[ORM\Table(name: 'report_document')]
#[ORM\EntityListeners([ReportDocumentListener::class])]
class ReportDocument
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    #[Groups(['report_document:read', 'commercial_report:read'])]
    private ?int $id = null;

    #[ORM\ManyToOne(targetEntity: CommercialReport::class, inversedBy: 'documents')]
    #[ORM\JoinColumn(name: 'commercial_report_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
    #[Groups(['report_document:read', 'report_document:write'])]
    private ?CommercialReport $commercialReport = null;

    #[ORM\Column(length: 255)]
    #[Groups(['report_document:read', 'commercial_report:read'])]
    private ?string $originalName = null;

    #[ORM\Column(length: 255, nullable: true)]
    #[Groups(['report_document:read', 'commercial_report:read'])]
    private ?string $fileName = null;

    #[ORM\Column(length: 100)]
    #[Groups(['report_document:read', 'commercial_report:read'])]
    private ?string $mimeType = null;

    #[ORM\Column]
    #[Groups(['report_document:read', 'commercial_report:read'])]
    private ?int $size = null;

    #[ORM\Column(type: 'datetime_immutable')]
    #[Groups(['report_document:read', 'commercial_report:read'])]
    private ?DateTimeImmutable $createdAt = null;

    #[ORM\ManyToOne(targetEntity: UserInterface::class)]
    #[ORM\JoinColumn(name: 'uploaded_by_id', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
    #[Groups(['report_document:read', 'commercial_report:read'])]
    private ?UserInterface $uploadedBy = null;

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

    public function getCommercialReport(): ?CommercialReport
    {
        return $this->commercialReport;
    }

    public function setCommercialReport(?CommercialReport $commercialReport): static
    {
        $this->commercialReport = $commercialReport;

        return $this;
    }

    public function getOriginalName(): ?string
    {
        return $this->originalName;
    }

    public function setOriginalName(string $originalName): static
    {
        $this->originalName = $originalName;

        return $this;
    }

    public function getFileName(): ?string
    {
        return $this->fileName;
    }

    public function setFileName(?string $fileName): static
    {
        $this->fileName = $fileName;

        return $this;
    }

    public function getMimeType(): ?string
    {
        return $this->mimeType;
    }

    public function setMimeType(string $mimeType): static
    {
        $this->mimeType = $mimeType;

        return $this;
    }

    public function getSize(): ?int
    {
        return $this->size;
    }

    public function setSize(int $size): static
    {
        $this->size = $size;

        return $this;
    }

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

    public function setCreatedAt(DateTimeImmutable $createdAt): static
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    public function getUploadedBy(): ?UserInterface
    {
        return $this->uploadedBy;
    }

    public function setUploadedBy(?UserInterface $uploadedBy): static
    {
        $this->uploadedBy = $uploadedBy;

        return $this;
    }
}
