<?php
declare(strict_types=1);

namespace App\Foundation;

use App\Core\Database;
use Throwable;

final class HealthReport
{
    /** @return array<int,array<string,string>> */
    public function checks(): array
    {
        $checks = [];
        $checks[] = $this->check('PHP', version_compare(PHP_VERSION, '8.1.0', '>='), PHP_VERSION, 'PHP 8.1 minimum');
        $checks[] = $this->check('Extension PDO', extension_loaded('pdo'), extension_loaded('pdo') ? 'active' : 'absente', 'Requise');
        $checks[] = $this->check('Extension JSON', extension_loaded('json'), extension_loaded('json') ? 'active' : 'absente', 'Requise');
        $checks[] = $this->check('Dossier storage', is_dir(BASE_PATH . '/storage') && is_writable(BASE_PATH . '/storage'), BASE_PATH . '/storage', 'Doit être accessible en écriture');
        $checks[] = $this->databaseCheck();
        $checks[] = $this->tableCheck('axiom_modules');
        $checks[] = $this->tableCheck('axiom_metadata_entities');
        return $checks;
    }

    /** @return array<string,string> */
    private function check(string $name, bool $ok, string $value, string $expected): array
    {
        return [
            'name' => $name,
            'status' => $ok ? 'ok' : 'warning',
            'value' => $value,
            'expected' => $expected,
        ];
    }

    /** @return array<string,string> */
    private function databaseCheck(): array
    {
        try {
            Database::getConnection()->query('SELECT 1');
            return $this->check('Base de données', true, 'connexion active', 'Connexion PDO active');
        } catch (Throwable $e) {
            return $this->check('Base de données', false, $e->getMessage(), 'Connexion PDO active');
        }
    }

    /** @return array<string,string> */
    private function tableCheck(string $table): array
    {
        try {
            $pdo = Database::getConnection();
            $stmt = $pdo->prepare('SHOW TABLES LIKE :table_name');
            $stmt->execute(['table_name' => $table]);
            $exists = (bool)$stmt->fetchColumn();
            return $this->check('Table ' . $table, $exists, $exists ? 'présente' : 'absente', 'Migration V8 installée');
        } catch (Throwable $e) {
            return $this->check('Table ' . $table, false, $e->getMessage(), 'Migration V8 installée');
        }
    }
}
