<?php

declare(strict_types=1);

namespace App\Framework\Database\Migration;

use App\Framework\Database\Exception\DatabaseException;

final class MigrationLoader
{
    private string $migrationsPath;

    public function __construct(string $migrationsPath)
    {
        $this->migrationsPath = $migrationsPath;
    }

    /**
     * @return Migration[]
     */
    public function loadMigrations(): array
    {
        if (!is_dir($this->migrationsPath)) {
            throw new DatabaseException("Migrations directory does not exist: {$this->migrationsPath}");
        }

        $migrations = [];
        $files = glob($this->migrationsPath . '/*.php');

        foreach ($files as $file) {
            $className = $this->getClassNameFromFile($file);

            if (!$className) {
                continue;
            }

            require_once $file;

            if (!class_exists($className)) {
                continue;
            }

            $reflection = new \ReflectionClass($className);

            if (!$reflection->implementsInterface(Migration::class)) {
                continue;
            }

            $migration = $reflection->newInstance();
            $migrations[] = $migration;
        }

        usort($migrations, fn($a, $b) => $a->getVersion() <=> $b->getVersion());

        return $migrations;
    }

    private function getClassNameFromFile(string $file): ?string
    {
        $content = file_get_contents($file);

        $namespace = '';
        if (preg_match('/namespace\s+([^;]+);/i', $content, $matches)) {
            $namespace = $matches[1] . '\\';
        }

        if (preg_match('/class\s+([^\s{]+)/i', $content, $matches)) {
            return $namespace . $matches[1];
        }

        return null;
    }
}
