<?php


namespace App\Model\Facades\Writers;


use App\Model\Entities\Components\Gallery\Gallery;
use App\Model\Facades\Readers\GalleryReader;
use App\Model\Facades\Readers\ImageReader;
use App\Model\Facades\Readers\TemplateReader;
use App\Model\Services\GalleryService;
use Throwable;

class GalleryWriter extends BaseWriter
{
    /** @var  GalleryService */
    protected $galleryService;
    /** @var  GalleryReader */
    protected $galleryReader;
    /** @var  TemplateReader */
    protected $templateReader;
    /** @var  ImageReader */
    protected $imageReader;

    /**
     * @param GalleryService $galleryService
     * @param GalleryReader $galleryReader
     * @param TemplateReader $templateReader
     * @param ImageReader $imageReader
     */
    public function inject(GalleryService $galleryService, GalleryReader $galleryReader, TemplateReader $templateReader, ImageReader $imageReader)
    {
        $this->galleryService = $galleryService;
        $this->galleryReader = $galleryReader;
        $this->templateReader = $templateReader;
        $this->imageReader = $imageReader;
    }

    /**
     * @param $template
     * @param string $name
     * @param string $description
     * @param bool $publish
     * @return Gallery
     * @throws Throwable
     */
    public function createGallery($template, string $name, string $description = null, $publish = false) : Gallery
    {
        $templateEntity = $this->templateReader->validateGalleryTemplate($template);

        try {
            $this->beginTransaction();
            $gallery = $this->galleryService->createGallery($this->getLoggedInUser(), $templateEntity, $name, $description);
            if ($publish) {
                $this->publishGallery($gallery);
            }
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $gallery;
    }

    /**
     * @param $gallery
     * @param $image
     * @throws Throwable
     */
    public function attachImage($gallery, $image)
    {
        $galleryEntity = $this->galleryReader->validateGallery($gallery);
        $imageEntity = $this->imageReader->validateImage($image);

        try {
            $this->beginTransaction();
            $galleryEntity->addImage($imageEntity);
            $galleryEntity->setEditedBy($this->getLoggedInUser());
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }
    }

    /**
     * @param $gallery
     * @return Gallery
     * @throws Throwable
     */
    public function publishGallery($gallery) : Gallery
    {
        $galleryEntity = $this->galleryReader->validateGallery($gallery);

        try {
            $this->beginTransaction();
            $galleryEntity->setState(Gallery::ACTIVE);
            $galleryEntity->setEditedBy($this->getLoggedInUser());
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $galleryEntity;
    }
}