<?php
declare(strict_types=1);

namespace App\Services;

use App\Core\Database;
use PDO;
use Throwable;

final class AuditSummaryService
{
    /** @return array<string,mixed> */
    public function report(): array
    {
        try {
            $pdo = Database::connection();
            $candidates = ['axiom_audit_logs', 'cda_audit_logs', 'audit_logs', 'logs_audit'];
            $table = null;
            $check = $pdo->prepare('SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=:table');
            foreach ($candidates as $candidate) {
                $check->execute(['table' => $candidate]);
                if ((int)$check->fetchColumn() > 0) {
                    $table = $candidate;
                    break;
                }
            }

            if ($table === null) {
                return ['status' => 'warning', 'table' => null, 'total' => 0, 'last_24h' => 0, 'recent' => [], 'message' => 'Aucune table de journal d’audit reconnue.'];
            }

            $total = (int)$pdo->query('SELECT COUNT(*) FROM `' . $table . '`')->fetchColumn();
            $columns = $this->columns($pdo, $table);
            $dateColumn = $this->firstExisting($columns, ['created_at', 'date_creation', 'occurred_at', 'date_action']);
            $last24h = 0;
            if ($dateColumn !== null) {
                $last24h = (int)$pdo->query('SELECT COUNT(*) FROM `' . $table . '` WHERE `' . $dateColumn . '` >= DATE_SUB(NOW(), INTERVAL 1 DAY)')->fetchColumn();
            }

            $recent = [];
            $order = $dateColumn !== null ? '`' . $dateColumn . '` DESC' : '1 DESC';
            $statement = $pdo->query('SELECT * FROM `' . $table . '` ORDER BY ' . $order . ' LIMIT 5');
            foreach ($statement->fetchAll(PDO::FETCH_ASSOC) as $row) {
                $recent[] = [
                    'date' => (string)($row[$dateColumn ?? ''] ?? ''),
                    'user' => (string)($row[$this->firstExisting($columns, ['user_id', 'utilisateur_id', 'actor_id', 'created_by']) ?? ''] ?? '—'),
                    'action' => (string)($row[$this->firstExisting($columns, ['action', 'event', 'operation', 'libelle']) ?? ''] ?? 'Évènement'),
                    'module' => (string)($row[$this->firstExisting($columns, ['module', 'entity_type', 'contexte']) ?? ''] ?? '—'),
                ];
            }

            return ['status' => 'ok', 'table' => $table, 'total' => $total, 'last_24h' => $last24h, 'recent' => $recent, 'message' => 'Journal d’audit disponible.'];
        } catch (Throwable $e) {
            return ['status' => 'warning', 'table' => null, 'total' => 0, 'last_24h' => 0, 'recent' => [], 'message' => $e->getMessage()];
        }
    }

    /** @return array<int,string> */
    private function columns(PDO $pdo, string $table): array
    {
        $statement = $pdo->prepare('SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=:table');
        $statement->execute(['table' => $table]);
        return array_map('strval', $statement->fetchAll(PDO::FETCH_COLUMN));
    }

    /** @param array<int,string> $available @param array<int,string> $candidates */
    private function firstExisting(array $available, array $candidates): ?string
    {
        foreach ($candidates as $candidate) {
            if (in_array($candidate, $available, true)) {
                return $candidate;
            }
        }
        return null;
    }
}
