<?php


namespace App\Model\Facades\Writers;


use App\Model\Entities\Components\Forum\Forum;
use App\Model\Exceptions\Db\NullTemplateException;
use App\Model\Facades\Readers\ForumReader;
use App\Model\Facades\Readers\TemplateReader;
use App\Model\Services\ForumService;
use App\Model\Services\MessengerService;
use Throwable;

class ForumWriter extends BaseWriter
{
    /** @var  ForumService */
    protected $forumService;
    /** @var  MessengerService */
    protected $messengerService;
    /** @var  ForumReader */
    protected $forumReader;
    /** @var  TemplateReader */
    protected $templateReader;

    public function inject(ForumService $forumService, MessengerService $messengerService, ForumReader $forumReader, TemplateReader $templateReader)
    {
        $this->forumService = $forumService;
        $this->messengerService = $messengerService;
        $this->forumReader = $forumReader;
        $this->templateReader = $templateReader;
    }

    public function createForum($name, $description = null, $template = null, $parent = null, $publish = false) : Forum
    {
        if ($template !== null) {
            $template = $this->templateReader->validateForumTemplate($template);
        }
        if ($parent !== null) {
            $parent = $this->forumReader->validateForum($parent);
        } elseif ($template === null) {
            throw new NullTemplateException();
        }

        try {
            $this->beginTransaction();
            $forum = $this->forumService->createForum($this->getLoggedInUser(), $name, $description, $template, $parent, $publish);
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $forum;
    }

    public function createTopic($forum, string $title, string $description)
    {
        $forumEntity = $this->forumReader->validateForum($forum);

        try {
            $this->beginTransaction();
            $topic = $this->forumService->createTopic($this->getLoggedInUser(), $forumEntity, $title, $description);
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $topic;
    }

    public function createPost($topic, string $title, string $message, $reply = null)
    {
        if ($reply !== null) {
            $reply = $this->forumReader->validatePost($reply);
        }
        $topicEntity = $this->forumReader->validateTopic($topic);

        try {
            $this->beginTransaction();
            $post = $this->messengerService->createPost($this->getLoggedInUser(), $topicEntity, $title, $message, $reply);
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $post;
    }
}