<?php

declare(strict_types=1);

namespace App\Framework\Filesystem;

use App\Framework\Core\ValueObjects\Byte;
use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\Filesystem\ValueObjects\FileMetadata;
use App\Framework\Filesystem\ValueObjects\FilePath;

/**
 * Clean File value object representing a file path with metadata.
 * File operations are handled by FileSystemService for better separation of concerns.
 */
final readonly class File
{
    public function __construct(
        public FilePath $path,
        public FileMetadata $metadata
    ) {
    }

    /**
     * Create File from SplFileInfo
     */
    public static function fromSplFileInfo(\SplFileInfo $fileInfo): self
    {
        $path = FilePath::create($fileInfo->getPathname());
        $metadata = new FileMetadata(
            size: $fileInfo->getSize() ?: 0,
            lastModified: $fileInfo->getMTime() ?: 0,
            mimeType: 'application/octet-stream', // Default, can be determined by FileSystemService
            isReadable: $fileInfo->isReadable(),
            isWritable: $fileInfo->isWritable()
        );

        return new self($path, $metadata);
    }

    /**
     * Get path as FilePath object
     */
    public function getPath(): FilePath
    {
        return $this->path;
    }

    /**
     * Get path as string
     */
    public function getPathString(): string
    {
        return $this->path->toString();
    }

    /**
     * Get file metadata
     */
    public function getMetadata(): FileMetadata
    {
        return $this->metadata;
    }

    /**
     * Get modification time as Timestamp
     */
    public function getModificationTime(): Timestamp
    {
        return Timestamp::fromFloat($this->metadata->lastModified);
    }

    /**
     * Get file size as Byte object
     */
    public function getSize(): Byte
    {
        return Byte::fromBytes($this->metadata->size);
    }

    /**
     * Get filename from path
     */
    public function getFilename(): string
    {
        return $this->path->getFilename();
    }

    /**
     * Get file extension
     */
    public function getExtension(): string
    {
        return $this->path->getExtension();
    }

    /**
     * Get directory path
     */
    public function getDirectory(): FilePath
    {
        return $this->path->getDirectory();
    }

    /**
     * Check if file has specific extension
     */
    public function hasExtension(string $extension): bool
    {
        return $this->path->hasExtension($extension);
    }
}
