<?php

declare(strict_types=1);

require_once __DIR__ . '/../vendor/autoload.php';

use Core\App;
use Core\Database;
use Core\Dispatcher;
use Core\MigrationManager;
use Core\Request;
use Core\Router;

$tempMigrationPath = sys_get_temp_dir() . '/mvc_migrations_' . uniqid('', true);
mkdir($tempMigrationPath, 0777, true);

$migrationFile = $tempMigrationPath . '/20260509_120000_create_projects_table.php';
file_put_contents($migrationFile, <<<'PHP'
<?php

declare(strict_types=1);

use Core\Database;
use Core\Migration;

return new class extends Migration
{
    public function up(Database $database): void
    {
        $database->execute('CREATE TABLE projects (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(100) NOT NULL)');
    }

    public function down(Database $database): void
    {
        $database->execute('DROP TABLE IF EXISTS projects');
    }
};
PHP
);

$memoryDatabase = new Database([
    'dsn' => 'sqlite::memory:',
    'options' => [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ],
]);

$migrationManager = new MigrationManager($memoryDatabase, $tempMigrationPath);
$ran = $migrationManager->runPending();

if ($ran !== ['20260509_120000_create_projects_table.php']) {
    echo "FAIL: migration manager did not apply the expected migration\n";
    exit(1);
}

$projectTable = $memoryDatabase->first("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'projects'");

if ($projectTable === null) {
    echo "FAIL: migration up() did not create the projects table\n";
    exit(1);
}

$rolledBack = $migrationManager->rollback();

if ($rolledBack !== ['20260509_120000_create_projects_table.php']) {
    echo "FAIL: migration manager did not roll back the expected migration\n";
    exit(1);
}

$projectTableAfterRollback = $memoryDatabase->first("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'projects'");

if ($projectTableAfterRollback !== null) {
    echo "FAIL: migration down() did not remove the projects table\n";
    exit(1);
}

$createdMigrationPath = $migrationManager->make('create_tasks_table');

if (!file_exists($createdMigrationPath)) {
    echo "FAIL: migration manager did not create a migration file\n";
    exit(1);
}

$router = new Router();
$app = new App();

(new MigrationManager(database(), __DIR__ . '/../database/migrations'))->runPending();

require_once __DIR__ . '/../routes/web.php';

$router->get('/hello/{name}', function (string $name) {
    return 'Hello, ' . $name;
});

$request = new Request([], [], [
    'REQUEST_METHOD' => 'GET',
    'REQUEST_URI' => '/hello/Daniel',
]);

$response = (new Dispatcher($router, $app))->dispatch($request);

if ($response->status() !== 200) {
    echo "FAIL: expected status 200\n";
    exit(1);
}

if ($response->content() !== 'Hello, Daniel') {
    echo "FAIL: unexpected response content\n";
    exit(1);
}

echo "PASS: migration manager and route dispatch work\n";
