<?php

namespace Opentalent\OtTemplating\ViewHelpers\Events;

use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
use Opentalent\OtCore\Logging\OtLogger;
use Opentalent\OtCore\ViewHelpers\OtAbstractViewHelper;
use Opentalent\OtCore\Domain\Repository\EventRepository;
use Opentalent\OtCore\Exception\ApiRequestException;

/**
 *   This view helper provides an ApiPagedCollection named according to the 'as' variable
 *   and which contains the next events of the structure
 *
 *     {namespace ot=Opentalent\OtTemplating\ViewHelpers}
 *
 *     <ot:events.getNext as="events"
 *                        organizationId="{settings.organizationId}"
 *                        limit="{settings.eventsLimit}"
 *                        period="{settings.eventsPeriod}">
 *          <f:debug>{events}</f:debug>
 *     </ot:events.getNext>
 *
 * @package Opentalent\OtTemplating\ViewHelpers
 */
class GetNextViewHelper extends OtAbstractViewHelper {

    use TemplateVariableViewHelperTrait;

    /**
     * >> Required to prevent typo3 to escape the html output
     * @var boolean
     */
    protected $escapeOutput = false;

    /**
     * @var EventRepository
     *
     */
    protected $eventRepository;

    /**
     * -- This method is expected by Fluid --
     * Declares the viewhelper's parameters
     */
    public function initializeArguments()
    {
        $this->registerArgument(
            'as',
            'string',
            'Name of the returned array',
            true
        );
        $this->registerArgument(
            'organizationId',
            'integer',
            'Id of the current structure',
            true
        );
        $this->registerArgument(
            'limit',
            'integer',
            'Max number of events to return (min: 1, max: 24)',
            false,
            5
        );
        $this->registerArgument(
            'period',
            'integer',
            'Limit the result to the N next weeks',
            false,
            8
        );
        $this->registerArgument(
            'fromParents',
            'bool',
            'Get events from parents instead',
            false,
            0
        );
        $this->registerArgument(
            'fromChildren',
            'bool',
            'Get events from children instead',
            false,
            0
        );
    }

    /**
     *  -- This method is expected by Fluid --
     * Renders the content as html
     *
     * @return string
     * @throws ApiRequestException
     * @throws \Exception
     */
    public function render()
    {

        // Get current settings
        $as = $this->arguments['as'];
        $organizationId = $this->arguments['organizationId'];
        $limit = $this->arguments['limit'];
        $period = $this->arguments['period'];
        $fromParents = $this->arguments['fromParents'];
        $fromChildren = $this->arguments['fromChildren'];

        if (!$organizationId) {
            $this->throwException('Organization id is missing');
        }

        $fromDate = new \DateTime();
        $toDate = null;
        if ($period > 0) {
            $nbDays = 7 * $period;
            $toDate = new \DateTime();
            $interval = new \DateInterval('P' . $nbDays . 'D');
            $toDate->add($interval);
        }
        if ($limit < 1) {
            $limit = 1; // $limit can not be lesser than 1
        }
        if ($limit > 24) {
            $limit = 24; // $limit can not be higher than 24
        }

        // Get next events of the structure
        try {
            if ($fromChildren) {
                // Network: Get the next events of the parent structures
                $events = $this->eventRepository->findChildrenByOrganizationId($organizationId, $fromDate, $toDate, $limit);
            } else if ($fromParents) {
                // Simple structure: Get the next events of the parent structures
                $events = $this->eventRepository->findParentsByOrganizationId($organizationId, $fromDate, $toDate, $limit);
            } else {
                $events = $this->eventRepository->findByOrganizationId($organizationId, $fromDate, $toDate, $limit);
            }
        } catch (ApiRequestException $e) {
            OtLogger::error(sprintf('API Error: %s', $e->getMessage()));
            $events = [];
        }

        $variables = [$as => $events];
        return $this->renderChildrenWithVariables($variables);
    }

    /**
     * @param EventRepository $eventRepository
     */
    public function injectEventRepository(EventRepository $eventRepository)
    {
        $this->eventRepository = $eventRepository;
    }
}
