<?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\ChillEntityRenderInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
 * @implements ChillEntityRenderInterface<SocialIssue>
 */
class SocialIssueRender implements ChillEntityRenderInterface
{
    public const AND_CHILDREN_MENTION = 'show_and_children_mention';

    public const DEFAULT_ARGS = [
        self::SEPARATOR_KEY => ' > ',
        self::SHOW_AND_CHILDREN => false,
        self::AND_CHILDREN_MENTION => 'social_issue.and children',
    ];

    public const SEPARATOR_KEY = 'default.separator';

    /**
     * Show a mention "and children" on each SocialIssue, if the social issue
     * has at least one child.
     */
    public const SHOW_AND_CHILDREN = 'show_and_children';

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

    public function renderBox($socialIssue, array $options): string
    {
        $options = array_merge(self::DEFAULT_ARGS, $options);
        // give some help to twig: an array of parents
        $parents = $this->buildParents($socialIssue);

        return $this
            ->engine
            ->render(
                '@ChillPerson/Entity/social_issue.html.twig',
                [
                    'socialIssue' => $socialIssue,
                    'parents' => $parents,
                    'options' => $options,
                ]
            );
    }

    public function renderString($socialIssue, array $options): string
    {
        /** @var SocialIssue $socialIssue */
        $options = array_merge(self::DEFAULT_ARGS, $options);

        $titles = [$this->translatableStringHelper->localize($socialIssue->getTitle())];

        // loop to parent, until root
        while ($socialIssue->hasParent()) {
            $socialIssue = $socialIssue->getParent();
            $titles[] = $this->translatableStringHelper->localize(
                $socialIssue->getTitle()
            );
        }

        $titles = \array_reverse($titles);

        $title = \implode($options[self::SEPARATOR_KEY], $titles);

        if ($options[self::SHOW_AND_CHILDREN] && $socialIssue->hasChildren()) {
            $title .= ' ('.$this->translator->trans($options[self::AND_CHILDREN_MENTION]).')';
        }

        return $title;
    }

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

    private function buildParents(SocialIssue $socialIssue): array
    {
        $parents = [];

        while ($socialIssue->hasParent()) {
            $socialIssue = $parents[] = $socialIssue->getParent();
        }

        return $parents;
    }
}
