<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;
use App\Repository\DocumentVersionRepository;

#[ORM\Entity(repositoryClass: DocumentVersionRepository::class)]
class DocumentVersion
{
    public const INGEST_PENDING = 'PENDING';
    public const INGEST_RUNNING = 'RUNNING';
    public const INGEST_INDEXED = 'INDEXED';
    public const INGEST_FAILED  = 'FAILED';

    public const INGEST_STATUSES = [
        self::INGEST_PENDING,
        self::INGEST_RUNNING,
        self::INGEST_INDEXED,
        self::INGEST_FAILED,
    ];

    #[ORM\Id]
    #[ORM\Column(type: 'uuid', unique: true)]
    private Uuid $id;

    #[ORM\ManyToOne(targetEntity: Document::class, inversedBy: 'versions')]
    #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
    private Document $document;

    #[ORM\Column(type: 'integer')]
    private int $versionNumber;

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

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

    #[ORM\Column(length: 20)]
    private string $ingestStatus = self::INGEST_PENDING;

    #[ORM\ManyToOne(targetEntity: User::class)]
    #[ORM\JoinColumn(nullable: false)]
    private User $createdBy;

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

    #[ORM\Column(type: 'boolean')]
    private bool $isActive = false;

    public function __construct()
    {
        $this->id = Uuid::v4();
        $this->createdAt = new \DateTimeImmutable();
    }

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

    public function setDocument(Document $document): void
    {
        $this->document = $document;

        if (!$document->getVersions()->contains($this)) {
            $document->addVersion($this);
        }
    }

    public function getDocument(): Document
    {
        return $this->document;
    }

    public function getVersionNumber(): int
    {
        return $this->versionNumber;
    }

    public function setVersionNumber(int $number): void
    {
        $this->versionNumber = $number;
    }

    public function setFilePath(string $path): void
    {
        $this->filePath = $path;
    }

    public function getFilePath(): string
    {
        return $this->filePath;
    }

    public function setChecksum(string $checksum): void
    {
        $this->checksum = $checksum;
    }

    public function getChecksum(): string
    {
        return $this->checksum;
    }

    public function setIngestStatus(string $status): void
    {
        if (!in_array($status, self::INGEST_STATUSES, true)) {
            throw new \InvalidArgumentException('Invalid ingest status.');
        }

        $this->ingestStatus = $status;
    }

    public function getIngestStatus(): string
    {
        return $this->ingestStatus;
    }

    public function isIndexed(): bool
    {
        return $this->ingestStatus === self::INGEST_INDEXED;
    }

    public function setCreatedBy(User $user): void
    {
        $this->createdBy = $user;
    }

    public function getCreatedBy(): User
    {
        return $this->createdBy;
    }

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

    public function setActive(bool $active): void
    {
        $this->isActive = $active;
    }

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

    public function getFileExtension(): string
    {
        return mb_strtolower(pathinfo($this->filePath, PATHINFO_EXTENSION));
    }

    public function getFileTypeLabel(): string
    {
        return match ($this->getFileExtension()) {
            'pdf' => 'PDF',
            'txt' => 'Text',
            'md'  => 'Markdown',
            default => strtoupper($this->getFileExtension()),
        };
    }
}
