<?php

declare(strict_types=1);

namespace App\Framework\Http;

use App\Framework\Filesystem\ValueObjects\FilePath;

final readonly class UploadedFile
{
    public function __construct(
        public string $name,
        public string $type,
        public int $size,
        public string $tmpName,
        public UploadError $error,
        private bool $skipValidation = false,
        private ?MimeTypeDetector $mimeTypeDetector = null
    ) {
        if (! $this->skipValidation && $this->isValid() === false) {
            throw new \InvalidArgumentException("Invalid uploaded file: {$this->name}");
        }
    }

    public function getExtension(): ?string
    {
        return pathinfo($this->name, PATHINFO_EXTENSION) ?: null;
    }

    public function getFileName(): string
    {
        return pathinfo($this->name, PATHINFO_FILENAME);
    }

    private function isValid(): bool
    {
        return $this->error === UploadError::OK && is_uploaded_file($this->tmpName);
    }

    public function getMimeType(): MimeTypeInterface
    {
        $detector = $this->mimeTypeDetector ?? new FilesystemMimeTypeDetector();
        return $detector->detect(FilePath::create($this->tmpName));
    }

    /**
     * Create an UploadedFile for testing without validation
     *
     * Uses MockMimeTypeDetector to return the specified type instead of detecting from file
     */
    public static function createForTesting(
        string $name,
        string $type,
        int $size,
        string $tmpName,
        UploadError $error = UploadError::OK
    ): self {
        return new self(
            $name,
            $type,
            $size,
            $tmpName,
            $error,
            skipValidation: true,
            mimeTypeDetector: MockMimeTypeDetector::fromString($type)
        );
    }
}
