<?php


namespace App\Model\Facades\Writers;


use App\Model\Entities\Templates\EventTemplate;
use App\Model\Entities\Templates\ForumTemplate;
use App\Model\Entities\Templates\GalleryTemplate;
use App\Model\Entities\Templates\NewsTemplate;
use App\Model\Entities\Templates\SiteTemplate;
use App\Model\Exceptions\Db\RecordNotFoundException;
use App\Model\Facades\Readers\SiteReader;
use App\Model\Interfaces\ITemplate;
use App\Model\Services\TemplateService;
use Throwable;

class TemplateWriter extends BaseWriter
{
    /** @var  TemplateService */
    protected $templateService;
    /** @var  SiteReader */
    protected $siteReader;

    public function inject(TemplateService $templateService, SiteReader $siteReader)
    {
        $this->templateService = $templateService;
        $this->siteReader = $siteReader;
    }

    public function createSiteTemplate($site, string $name, string $description, $parentTemplate = null) : SiteTemplate
    {
        $validTemplate = $this->validateParentTemplate($parentTemplate, SiteTemplate::class);

        return $this->createTemplate(SiteTemplate::class, $site, $name, $description, $validTemplate);
    }
    public function createNewsTemplate($site, string $name, string $description, $parentTemplate = null) : NewsTemplate
    {
        $validTemplate = $this->validateParentTemplate($parentTemplate, NewsTemplate::class);

        return $this->createTemplate(NewsTemplate::class, $site, $name, $description, $validTemplate);
    }

    public function createGalleryTemplate($site, string $name, string $description, $parentTemplate = null) : GalleryTemplate
    {
        $validTemplate = $this->validateParentTemplate($parentTemplate, GalleryTemplate::class);

        return $this->createTemplate(GalleryTemplate::class, $site, $name, $description, $validTemplate);
    }

    public function createForumTemplate($site, string $name, string $description, $parentTemplate = null) : ForumTemplate
    {
        $validTemplate = $this->validateParentTemplate($parentTemplate, ForumTemplate::class);

        return $this->createTemplate(ForumTemplate::class, $site, $name, $description, $validTemplate);
    }

    public function createEventTemplate($site, string $name, string $description, $parentTemplate = null) : EventTemplate
    {
        $validTemplate = $this->validateParentTemplate($parentTemplate, EventTemplate::class);

        return $this->createTemplate(EventTemplate::class, $site, $name, $description, $validTemplate);
    }

    protected function createTemplate(string $class, $site, string $name, string $description, $parentTemplate = null) : ITemplate
    {
        $siteEntity = $this->siteReader->validateSite($site);

        try {
            $this->beginTransaction();
            $template = $this->templateService->createTemplate($class, $this->getLoggedInUser(), $siteEntity, $name, $description, $parentTemplate);
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $template;
    }

    protected function validateParentTemplate($template, $class)
    {
        if ($template === null) {
            return null;
        }

        if ($template instanceof $class) {
            return $template;
        }

        $templateEntity = $this->templateService->findTemplateById($template);
        if ($templateEntity instanceof $class) {
            return $template;
        }

        throw new RecordNotFoundException();
    }
}