<?php
declare(strict_types=1);

namespace App\Services;

use App\Core\Database;
use Throwable;

final class SystemConsistencyService
{
    /** @return array<string,mixed> */
    public function report(): array
    {
        $issues = [];
        $checks = [];

        $paths = [
            'app' => BASE_PATH . '/app',
            'config' => BASE_PATH . '/config',
            'public' => BASE_PATH . '/public',
            'storage' => BASE_PATH . '/storage',
            'updates' => BASE_PATH . '/storage/updates',
            'backups' => BASE_PATH . '/storage/backups',
        ];
        foreach ($paths as $name => $path) {
            $exists = is_dir($path);
            $writableRequired = in_array($name, ['storage', 'updates', 'backups'], true);
            $writable = !$writableRequired || ($exists && is_writable($path));
            $ok = $exists && $writable;
            $checks[] = ['type' => 'directory', 'name' => $name, 'status' => $ok ? 'ok' : 'warning', 'message' => !$exists ? 'Dossier absent' : (!$writable ? 'Dossier non inscriptible' : 'Disponible')];
            if (!$ok) {
                $issues[] = $name . ' : ' . (!$exists ? 'absent' : 'non inscriptible');
            }
        }

        try {
            $pdo = Database::connection();
            $required = [
                'cda_update_packages' => ['statut', 'version_package', 'backup_job_id', 'journal_path'],
                'axiom_modules' => ['code', 'name', 'version', 'module_type', 'enabled', 'config_json'],
                'axiom_migrations' => ['version'],
            ];
            $query = $pdo->prepare('SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=:table');
            foreach ($required as $table => $columns) {
                $query->execute(['table' => $table]);
                $available = array_map('strval', $query->fetchAll(\PDO::FETCH_COLUMN));
                if ($available === []) {
                    $checks[] = ['type' => 'table', 'name' => $table, 'status' => 'warning', 'message' => 'Table absente'];
                    $issues[] = 'Table absente : ' . $table;
                    continue;
                }
                $missing = array_values(array_diff($columns, $available));
                $checks[] = ['type' => 'table', 'name' => $table, 'status' => $missing === [] ? 'ok' : 'warning', 'message' => $missing === [] ? 'Structure conforme' : 'Colonnes absentes : ' . implode(', ', $missing)];
                if ($missing !== []) {
                    $issues[] = $table . ' : ' . implode(', ', $missing);
                }
            }
        } catch (Throwable $e) {
            $issues[] = 'Contrôle SQL impossible : ' . $e->getMessage();
        }

        return [
            'status' => $issues === [] ? 'ok' : 'warning',
            'issues' => $issues,
            'checks' => $checks,
            'message' => $issues === [] ? 'Aucune incohérence bloquante détectée.' : count($issues) . ' incohérence(s) à examiner.',
        ];
    }
}
