<?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\CmsBundle\Controller\Page;

use Contao\ArticleModel;
use Contao\CoreBundle\DependencyInjection\Attribute\AsPage;
use Contao\CoreBundle\Exception\PageNotFoundException;
use Ferienpass\CmsBundle\Controller\AbstractController;
use Ferienpass\CmsBundle\Fragment\FragmentReference;
use Ferienpass\CoreBundle\Entity\User;
use Ferienpass\CoreBundle\HttpCache\CacheTag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

#[AsPage('applications', path: '{action?}')]
class ApplicationsPage extends AbstractController
{
    public function __invoke(?string $action, Request $request): Response
    {
        $this->denyAccessUnlessGranted('ROLE_USER');
        $this->initializeContaoFramework();

        // Tag with the user + participants so any change invalidates this page.
        $user = $this->getUser();
        if ($user instanceof User) {
            $tags = [CacheTag::user($user)];
            foreach ($user->getParticipants() as $participant) {
                $tags[] = CacheTag::participant($participant);
            }
            $this->tagResponse($tags);
        }

        $pageModel = $request->attributes->get('pageModel');

        $pageBuilder = $this->createPageBuilder($pageModel);

        $articles = ArticleModel::findPublishedByPidAndColumn($pageModel->id, 'main');

        switch ((string) $action) {
            case '':
                while (null !== $articles && $articles->next()) {
                    $pageBuilder->addFragment('main', new FragmentReference('ferienpass.fragment.article', ['id' => $articles->id]));
                }

                $pageBuilder->addFragment('main', new FragmentReference('ferienpass.fragment.application_list'));
                break;
            case 'prioritize':
                $pageBuilder->addFragment('main', new FragmentReference('ferienpass.fragment.applications_prioritize'));
                break;
            case 'abmelden':
                $pageBuilder->addFragment('main', new FragmentReference('ferienpass.fragment.attendance_withdraw'));
                break;
            default:
                throw new PageNotFoundException();
        }

        // /meine-anmeldungen (and its sub-actions) is always per-user. Force
        // private — belt-and-braces against the fragment-merge chain
        // breaking. See AbstractController::markPageAsPrivate().
        return $this->markPageAsPrivate($pageBuilder->getResponse());
    }
}
