<?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\AccompanyingPeriod\Events;

use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Notification;
use Chill\MainBundle\Notification\NotificationPersisterInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Event\Person\PersonAddressMoveEvent;
use Chill\PersonBundle\Notification\FlagProviders\PersonAddressMoveNotificationFlagProvider;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;

class PersonAddressMoveEventSubscriber implements EventSubscriberInterface
{
    public function __construct(private readonly \Twig\Environment $engine, private readonly NotificationPersisterInterface $notificationPersister, private readonly Security $security, private readonly TranslatorInterface $translator) {}

    public static function getSubscribedEvents(): array
    {
        return [
            PersonAddressMoveEvent::class => 'resetPeriodLocation',
        ];
    }

    public function resetPeriodLocation(PersonAddressMoveEvent $event)
    {
        if ($event->getPreviousAddress() !== $event->getNextAddress()
            && null !== $event->getPreviousAddress()
        ) {
            $person = $event->getPerson();

            foreach ($person->getCurrentAccompanyingPeriods() as $period) {
                if (AccompanyingPeriod::STEP_DRAFT === $period->getStep()) {
                    continue;
                }

                if (
                    $period->getPersonLocation() === $person
                        && (
                            $event->getMoveDate() >= $period->getLastLocationHistory()->getStartDate()
                            || $event->willChangeBeActiveAt(new \DateTimeImmutable('now'))
                        )
                    && null !== $period->getUser()
                    && $period->getUser() !== $this->security->getUser()
                ) {
                    // reset the location, back to an address
                    $period->setPersonLocation(null);
                    $period->setAddressLocation(Address::createFromAddress($event->getPreviousAddress()));

                    $notification = new Notification();
                    $notification
                        ->addAddressee($period->getUser())
                        ->setTitle($this->translator->trans('period_notification.Person locating period has moved'))
                        ->setRelatedEntityClass(AccompanyingPeriod::class)
                        ->setRelatedEntityId($period->getId())
                        ->setMessage($this->engine->render('@ChillPerson/AccompanyingPeriod/notification_location_user_on_period_has_moved.fr.txt.twig', [
                            'oldPersonLocation' => $person,
                            'period' => $period,
                        ]))
                        ->setType(PersonAddressMoveNotificationFlagProvider::FLAG);

                    $this->notificationPersister->persist($notification);
                }
            }
        }
    }
}
