<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\PersonBundle\Templating\Entity;

use Chill\MainBundle\Templating\Entity\BoxUtilsChillEntityRenderTrait;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Entity\Person;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
 * Render a Person.
 */
class PersonRender implements PersonRenderInterface
{
    use BoxUtilsChillEntityRenderTrait;

    public function __construct(
        private readonly ConfigPersonAltNamesHelper $configAltNamesHelper,
        private readonly \Twig\Environment $engine,
        private readonly TranslatorInterface $translator,
    ) {}

    public function renderBox($person, array $options): string
    {
        $params = [
            'addAltNames' => $options['addAltNames'] ?? $this->configAltNamesHelper->hasAltNames(),
            'addLink' => $options['addLink'] ?? false,
            'addEntity' => $options['addEntity'] ?? false,
            'addId' => $options['addId'] ?? false,
            'addInfo' => $options['addInfo'] ?? false,
            'addAge' => $options['addAge'] ?? false,
            'addCenter' => $options['addCenter'] ?? false,
            'address_multiline' => $options['address_multiline'] ?? false,
            'hLevel' => $options['hLevel'] ?? 3,
            'customButtons' => $options['customButtons'] ?? [],
            'customArea' => $options['customArea'] ?? [],
            'addDeath' => $options['addDeath'] ?? true,
            'addAgeBadge' => $options['addAgeBadge'] ?? false,
            'suffixText' => $options['suffixText'] ?? [],
        ];

        return
            $this->getDefaultOpeningBox('person').
            $this->engine->render('@ChillPerson/Entity/person.html.twig', [
                'person' => $person,
                'render' => $options['render'] ?? 'raw',
                'options' => $params,
            ]).
            $this->getDefaultClosingBox();
    }

    public function renderString($person, array $options): string
    {
        $options = array_merge(['addAge' => true], $options);

        if (null !== $person->getAge() && null === $person->getDeathDate() && $options['addAge']) {
            return $person->getFirstName().' '.$person->getLastName()
            .$this->addAltNames($person, false).' ('.$this->translator->trans('years_old', ['age' => $person->getAge()]).')';
        }

        if (null !== $person->getDeathDate() && $options['addAge']) {
            return $person->getFirstName().' '.$person->getLastName()
            .' (‡)'
            .$this->addAltNames($person, false);
        }

        return $person->getFirstName().' '.$person->getLastName()
            .$this->addAltNames($person, false);
    }

    public function supports($entity, array $options): bool
    {
        return $entity instanceof Person;
    }

    protected function addAltNames(Person $person, bool $addSpan): string
    {
        $str = '';

        if ($this->configAltNamesHelper->hasAltNames()) {
            $altNames = $this->configAltNamesHelper->getChoices();
            $isFirst = true;

            foreach ($person->getAltNames()->getIterator() as $altName) {
                /** @var \Chill\PersonBundle\Entity\PersonAltName $altName */
                if (\array_key_exists($altName->getKey(), $altNames)) {
                    if ($isFirst) {
                        $str .= ' (';
                        $isFirst = false;
                    } else {
                        $str .= ' ';
                    }

                    if ($addSpan) {
                        $str .= '<span class="altname altname-'.$altName->getKey().'">';
                    }
                    $str .= $altName->getLabel();

                    if ($addSpan) {
                        $str .= '</span>';
                    }
                }
            }

            if (!$isFirst) {
                $str .= ')';
            }
        }

        return $str;
    }
}
