<?php

namespace Opentalent\OtTemplating\ViewHelpers\Members;

use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
use Opentalent\OtCore\ViewHelpers\OtAbstractViewHelper;
use Opentalent\OtCore\Domain\Repository\MemberRepository;
use Opentalent\OtCore\Exception\ApiRequestException;

/**
 *   This view helper give access to an array named according to the 'as' variable
 *   and which contains the CA members of the structure classed by role
 *
 *     {namespace ot=Opentalent\OtTemplating\ViewHelpers}
 *
 *     <ot:members.getAllCa as="members"
 *                        organizationId="{settings.organizationId}">
 *          <f:debug>{members}</f:debug>
 *     </ot:members.getAllCa>
 *
 * @package Opentalent\OtTemplating\ViewHelpers
 */
class GetAllCaViewHelper extends OtAbstractViewHelper {

    use TemplateVariableViewHelperTrait;

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

    /**
     * @var MemberRepository
     *
     */
    protected MemberRepository $memberRepository;

    /**
     * -- 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(
            'groupByMissions',
            'bool',
            'If true, returns an array of the form [mission=>[members]], 
                       else the returned array is simply [members]',
            false,
            false
        );
    }

    /**
     * -- This method is expected by Fluid --
     * Renders the content as html
     *
     * @return string
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function render()
    {
        // Get current settings
        $as = $this->arguments['as'];
        $organizationId = $this->arguments['organizationId'];
        $groupByMissions = $this->arguments['groupByMissions'];

        // Missions to display (sorted)
        $missions = [
            'PRESIDENT',
            'HONORARY_PRESIDENT',
            'VICE_PRESIDENT',
            'VICE_PRESIDENT_OF_HONOR',
            'PRESIDENT_ASSISTANT',
            'HOUR_PRESIDENT',
            'SECRETARY',
            'ASSISTANT_SECRETARY',
            'TREASURER',
            'TREASURER_ASSISTANT',
            'MEMBER_OF_THE_BOARD',
            'MEMBER_OF_BOARD_OF_HONOR',
            'ACTIVE_COOPTED_BOARD_MEMBER',
            'ACTIVE_MEMBER_OF_THE_CA',
            'HONORARY_MEMBER',
            'YOUTH_REPRESENTATIVE'
        ];

        // Get members of the structure (only CA members)
        try {
            $collection = $this->memberRepository->findByOrganizationId($organizationId, true);
            $members = $collection->getMembers();
        } catch (ApiRequestException $e) {
            $this->logger->error(sprintf('API Error: %s', $e->getMessage()));
            $members = [];
        }

        $members = array_filter($members, function($m) use ($missions) {
            return array_search($m->getMission(), $missions) !== false;
        });

        // Sort by roles, then alphabetically by name
        usort($members,
            function($a, $b) use ($missions) {
                if ($a->getMission() != $b->getMission()) {
                    $ia = array_search($a->getMission(), $missions);
                    $ib = array_search($b->getMission(), $missions);
                    return $ia - $ib;
                } else {
                    return strcmp($a->getName(), $b->getName());
                }
            }
        );

        if ($groupByMissions && !empty($members)) {

            // Missions to display (sorted)
            $membersByMission = [];
            foreach ($missions as $mission) {
                $membersByMission[$mission] = [];
            }

            // Put members into their categories
            foreach ($members as $member) {
                if (array_key_exists($member->getMission(), $membersByMission)) {
                    array_push($membersByMission[$member->getMission()], $member);
                }
            }

            // Remove empty sections
            $members = array_filter($membersByMission);
        }

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

    /**
     * @param MemberRepository $memberRepository
     */
    public function injectMemberRepository(MemberRepository $memberRepository)
    {
        $this->memberRepository = $memberRepository;
    }
}
