<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\AdminBundle\Controller\Dashboard;

use Doctrine\ORM\EntityManagerInterface;
use Ferienpass\AdminBundle\Controller\TagsResponses;
use Ferienpass\CoreBundle\Entity\HostActivity;
use Ferienpass\CoreBundle\Entity\OfferLog;
use Ferienpass\CoreBundle\Entity\ParticipantLog;
use Ferienpass\CoreBundle\HttpCache\CacheTag;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\Response;

/**
 * ESI fragment rendering the recent-activity feed on the admin dashboard.
 * Tenant-global like the other dashboard widgets, so it carries the
 * {@see CacheTag::dashboard()} tag and the CacheInvalidationListener refreshes
 * it on attendance lifecycle events (a new application writes a ParticipantLog
 * in the same flush). NB: offer/host log entries are not yet wired to the tag —
 * they refresh on the next natural cache miss.
 */
class ActivityFeedController extends AbstractController
{
    use TagsResponses;

    private const int TTL = 31556926;

    public function __construct(private readonly EntityManagerInterface $entityManager)
    {
    }

    public function __invoke(#[Autowire(param: 'app.id')] string $appId): Response
    {
        if (!$this->isGranted('ROLE_ADMIN')) {
            return new Response('', Response::HTTP_NO_CONTENT);
        }

        $offerLogs = $this->entityManager->getRepository(OfferLog::class)->findBy([], ['createdAt' => 'DESC'], 20);
        $participantLogs = $this->entityManager->getRepository(ParticipantLog::class)->findBy([], ['createdAt' => 'DESC'], 20);
        $hostActivities = $this->entityManager->getRepository(HostActivity::class)->findBy([], ['createdAt' => 'DESC'], 20);

        $activities = array_merge($offerLogs, $participantLogs, $hostActivities);
        usort($activities, static fn ($a, $b) => $b->getCreatedAt() <=> $a->getCreatedAt());

        $activities = \array_slice($activities, 0, 20);

        $response = $this->render('@FerienpassAdmin/fragment/dashboard/activity_feed.html.twig', [
            'activities' => $activities,
        ]);

        // Tenant-global aggregate, shared across the tenant's admins — no Vary.
        $response->setPublic();
        $response->setSharedMaxAge(self::TTL);
        $this->tagResponse(CacheTag::dashboard($appId));

        return $response;
    }
}
