<?php

namespace App\EntityListener;

use App\Entity\Content;
use App\Entity\Content\Status;
use App\Entity\ContentVersion;
use App\Entity\User;
use App\Message\EventLogMessage;
use App\Service\ContentVersionService;
use App\Service\UserService;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Security\Core\Security;

final class ContentListener
{
    /**
     * @var MessageBusInterface
     */
    private $messageBus;
    /**
     * @var bool
     */
    private $dirty = false;
    /**
     * @var User|null
     */
    private $oldUser = null;
    /**
     * @var Status|null
     */
    private $oldStatus = null;
    /**
     * @var ContainerInterface
     */
    private $container;
    /**
     * @var Security
     */
    private $security;

    public function __construct(MessageBusInterface $messageBus, ContainerInterface $container, Security $security)
    {
        $this->messageBus = $messageBus;
        $this->container = $container;
        $this->security = $security;
    }

    /**
     * @ORM\PrePersist()
     *
     * @param Content $content
     */
    public function prePersist(Content $content)
    {
        if (null === $content->getTitle()) {
            if ($content->getCampaign()) {
                $content->setTitle('Content #'.($content->getCampaign()->getContents()->count() + 1));
            } else {
                $content->setTitle('Content');
            }
        }
    }

    /**
     * @ORM\PostPersist()
     */
    public function createFirstVersion(Content $content)
    {
        $contentVersion = (new ContentVersion())
            ->setContent($content)
            ->setDescription('')
            ->setAutosaved(false);

        if (!$this->security->getUser()) {
            $userService = $this->container->get(UserService::class);
            $contentVersion->setCreatedBy($userService->getUser(1));
        }

        $contentVersionService = $this->container->get(ContentVersionService::class);
        $contentVersionService->saveContentVersion($contentVersion);
    }

    /**
     * @ORM\PreUpdate()
     */
    public function preUpdate(Content $content, PreUpdateEventArgs $args)
    {
        $changeSet = $args->getEntityChangeSet();

        if (array_key_exists('user', $changeSet) || array_key_exists('status', $changeSet)) {
            if (array_key_exists('user', $changeSet)) {
                $this->oldUser = $changeSet['user'][0];
            }

            if (array_key_exists('status', $changeSet)) {
                $this->oldStatus = $changeSet['status'][0];
            }

            $this->dirty = true;
        }
    }

    /**
     * @ORM\PostUpdate()
     *
     * @param Content $content
     */
    public function updateEvenLog(Content $content)
    {
        if ($this->dirty) {
            $newUser = $this->oldUser ? $content->getUser() : null;
            $newStatus = $this->oldStatus ? $content->getStatus() : null;
            $this->messageBus->dispatch(new EventLogMessage($this->oldUser, $newUser, $this->oldStatus, $newStatus, $content));
        }
    }
}
