<?php

declare(strict_types=1);

namespace App\Controller\Admin;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/admin/system-logs')]
final class AdminSystemLogController extends AbstractController
{
    private string $logDir;

    public function __construct()
    {
        $this->logDir = \dirname(__DIR__, 3) . '/var/log';
    }

    #[Route('', name: 'admin_system_logs_index')]
    public function index(): Response
    {
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');

        $files = [];

        foreach (\glob($this->logDir . '/system*.log') ?: [] as $file) {
            $files[] = [
                'name' => \basename($file),
                'size' => \filesize($file),
                'mtime' => \filemtime($file),
            ];
        }

        \usort($files, fn($a, $b) => $b['mtime'] <=> $a['mtime']);

        return $this->render('admin/system_logs/index.html.twig', [
            'files' => $files,
        ]);
    }

    #[Route(
        '/view/{date}',
        name: 'admin_system_logs_view',
        requirements: ['date' => '\d{4}-\d{2}-\d{2}|current']
    )]
    public function view(string $date): Response
    {
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');

        if ($date === 'current') {
            $safeFilename = 'system.log';
        } else {
            $safeFilename = 'system-' . $date . '.log';
        }

        $path = $this->logDir . '/' . $safeFilename;

        if (!\file_exists($path)) {
            throw $this->createNotFoundException('Log file not found.');
        }

        $content = $this->readLastLines($path, 1000);

        return $this->render('admin/system_logs/view.html.twig', [
            'filename' => $safeFilename,
            'content'  => $content,
        ]);
    }

    private function readLastLines(string $file, int $lines = 1000): string
    {
        $handle = \fopen($file, 'rb');
        if (!$handle) {
            return 'Unable to open log file.';
        }

        $buffer = '';
        $chunkSize = 4096;
        $lineCount = 0;
        $pos = -1;

        \fseek($handle, 0, SEEK_END);
        $fileSize = \ftell($handle);

        while ($lineCount < $lines && -$pos < $fileSize) {
            $step = \min($chunkSize, $fileSize + $pos);
            \fseek($handle, $pos - $step, SEEK_END);
            $chunk = \fread($handle, $step);
            $buffer = $chunk . $buffer;
            $lineCount += \substr_count($chunk, "\n");
            $pos -= $step;
        }

        \fclose($handle);

        $linesArray = \explode("\n", $buffer);
        return \implode("\n", \array_slice($linesArray, -$lines));
    }
}