<?php

declare(strict_types=1);

namespace App\Framework\Development\HotReload;

use App\Framework\Core\ValueObjects\Timestamp;

/**
 * Represents a file change event
 */
final readonly class FileChangeEvent
{
    public function __construct(
        private string $path,
        private FileChangeType $type,
        private Timestamp $timestamp,
        private ?int $size = null,
        private ?string $hash = null
    ) {
    }

    public static function created(string $path): self
    {
        return new self(
            path: $path,
            type: FileChangeType::CREATED,
            timestamp: Timestamp::now()
        );
    }

    public static function modified(string $path, ?string $hash = null): self
    {
        return new self(
            path: $path,
            type: FileChangeType::MODIFIED,
            timestamp: Timestamp::now(),
            hash: $hash
        );
    }

    public static function deleted(string $path): self
    {
        return new self(
            path: $path,
            type: FileChangeType::DELETED,
            timestamp: Timestamp::now()
        );
    }

    public function getPath(): string
    {
        return $this->path;
    }

    public function getType(): FileChangeType
    {
        return $this->type;
    }

    public function getTimestamp(): Timestamp
    {
        return $this->timestamp;
    }

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

    public function getHash(): ?string
    {
        return $this->hash;
    }

    public function getRelativePath(string $basePath): string
    {
        if (str_starts_with($this->path, $basePath)) {
            return substr($this->path, strlen($basePath) + 1);
        }

        return $this->path;
    }

    public function isPhpFile(): bool
    {
        return str_ends_with($this->path, '.php');
    }

    public function isViewFile(): bool
    {
        return str_ends_with($this->path, '.view.php')
            || str_contains($this->path, '/views/');
    }

    public function isConfigFile(): bool
    {
        return str_contains($this->path, '/config/');
    }

    public function isAssetFile(): bool
    {
        return str_ends_with($this->path, '.css')
            || str_ends_with($this->path, '.js')
            || str_ends_with($this->path, '.ts')
            || str_ends_with($this->path, '.scss');
    }
}
