<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Attribute as Vich;

#[ORM\Entity]
#[Vich\Uploadable]
class AttestationCustom
{
    public const STATE_DRAFT = 'draft';
    public const STATE_SIGNED = 'signed';

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    private string $title;

    /** @var list<string> */
    #[ORM\Column(type: 'json')]
    private array $items = [];

    #[ORM\Column(length: 20, options: ['default' => 'draft'])]
    private string $state = self::STATE_DRAFT;

    #[ORM\Column(length: 64)]
    private string $hmac;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $pdfUnsigned = null;

    #[Vich\UploadableField(mapping: 'attestation_custom_pdf', fileNameProperty: 'pdfUnsigned')]
    private ?File $pdfUnsignedFile = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $pdfSigned = null;

    #[Vich\UploadableField(mapping: 'attestation_custom_signed_pdf', fileNameProperty: 'pdfSigned')]
    private ?File $pdfSignedFile = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $pdfAudit = null;

    #[Vich\UploadableField(mapping: 'attestation_custom_audit_pdf', fileNameProperty: 'pdfAudit')]
    private ?File $pdfAuditFile = null;

    #[ORM\Column]
    private \DateTimeImmutable $createdAt;

    #[ORM\Column(nullable: true)]
    private ?\DateTimeImmutable $signedAt = null;

    #[ORM\Column(nullable: true)]
    private ?\DateTimeImmutable $updatedAt = null;

    /**
     * @param list<string> $items
     */
    public function __construct(string $title, array $items)
    {
        $this->title = $title;
        $this->items = $items;
        $this->createdAt = new \DateTimeImmutable();
        $this->hmac = $this->generateHmac();
    }

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

    public function getTitle(): string
    {
        return $this->title;
    }

    public function setTitle(string $title): static
    {
        $this->title = $title;

        return $this;
    }

    /** @return list<string> */
    public function getItems(): array
    {
        return $this->items;
    }

    /** @param list<string> $items */
    public function setItems(array $items): static
    {
        $this->items = $items;

        return $this;
    }

    public function getState(): string
    {
        return $this->state;
    }

    public function setState(string $state): static
    {
        $this->state = $state;

        return $this;
    }

    public function getHmac(): string
    {
        return $this->hmac;
    }

    public function getReference(): string
    {
        return 'ATT_'.str_pad((string) ($this->id ?? 0), 5, '0', \STR_PAD_LEFT);
    }

    public function getPdfUnsigned(): ?string
    {
        return $this->pdfUnsigned;
    }

    public function setPdfUnsigned(?string $pdfUnsigned): static
    {
        $this->pdfUnsigned = $pdfUnsigned;

        return $this;
    }

    public function getPdfUnsignedFile(): ?File
    {
        return $this->pdfUnsignedFile;
    }

    public function setPdfUnsignedFile(?File $file): static
    {
        $this->pdfUnsignedFile = $file;
        if (null !== $file) {
            $this->updatedAt = new \DateTimeImmutable();
        }

        return $this;
    }

    public function getPdfSigned(): ?string
    {
        return $this->pdfSigned;
    }

    public function setPdfSigned(?string $pdfSigned): static
    {
        $this->pdfSigned = $pdfSigned;

        return $this;
    }

    public function getPdfSignedFile(): ?File
    {
        return $this->pdfSignedFile;
    }

    public function setPdfSignedFile(?File $file): static
    {
        $this->pdfSignedFile = $file;
        if (null !== $file) {
            $this->updatedAt = new \DateTimeImmutable();
        }

        return $this;
    }

    public function getPdfAudit(): ?string
    {
        return $this->pdfAudit;
    }

    public function setPdfAudit(?string $pdfAudit): static
    {
        $this->pdfAudit = $pdfAudit;

        return $this;
    }

    public function getPdfAuditFile(): ?File
    {
        return $this->pdfAuditFile;
    }

    public function setPdfAuditFile(?File $file): static
    {
        $this->pdfAuditFile = $file;
        if (null !== $file) {
            $this->updatedAt = new \DateTimeImmutable();
        }

        return $this;
    }

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

    public function getSignedAt(): ?\DateTimeImmutable
    {
        return $this->signedAt;
    }

    public function setSignedAt(?\DateTimeImmutable $signedAt): static
    {
        $this->signedAt = $signedAt;

        return $this;
    }

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

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

        return $this;
    }

    public function verifyHmac(): bool
    {
        return hash_equals($this->hmac, $this->generateHmac());
    }

    private function generateHmac(): string
    {
        $payload = implode('|', [
            'attestation_custom',
            $this->title,
            $this->createdAt->format('Y-m-d\TH:i:s'),
            json_encode($this->items),
        ]);

        return hash_hmac('sha256', $payload, 'ecosplay_attestation_secret');
    }
}
