<?php

namespace core\services\post;

use core\entities\Meta;
use core\entities\post\Post;
use core\entities\post\PostTag;
use core\forms\post\PostForm;
use core\helpers\PostHelper;
use core\repositories\post\PostCategoryRepository;
use core\repositories\post\PostRepository;
use core\repositories\post\PostTagRepository;
use core\services\TransactionManager;
use yii\base\Security;
use yii\helpers\Inflector;

class PostManageService
{
    private $posts;
    private $categories;
    private $tags;
    private $transaction;

    public function __construct(
        PostRepository $posts,
        PostCategoryRepository $categories,
        PostTagRepository $tags,
        TransactionManager $transaction
    )
    {
        $this->posts = $posts;
        $this->categories = $categories;
        $this->tags = $tags;
        $this->transaction = $transaction;
    }

    public function create(PostForm $form): Post
    {
        $category = $this->categories->get($form->category_id);

        $post = Post::create(
            $category->id,
            $form->title,
            $form->slug,
            $form->description,
            $form->content,
            $form->type_id,
            $form->published_at,
            $form->video,
            new Meta(
                $form->meta->title,
                $form->meta->description,
                $form->meta->keywords
            )
        );

        if ($form->image) {
            $post->setImage($form->image);
        }
        else if ($form->video) {
	        $src = 'https://i.ytimg.com/vi/' . PostHelper::parseYoutubeUrl($post->video) . '/maxresdefault.jpg';
	        $filename = (new Security())->generateRandomString(15) . '.jpg';
	        copy($src, \Yii::getAlias(Post::FILE_ORIGINAL_PATH . '/' . $post->id . '.jpg'));
	        $post->image = $filename;
        }

        $this->transaction->wrap(function () use ($post, $form) {

	        if (is_array($form->tags->new_tags) && !empty($form->tags->new_tags)) {
		        foreach ( $form->tags->new_tags as $tag_id => $tag_name ) {
			        if ( !$tag = $this->tags->findByName( $tag_name, $form->type_id ) ) {
				        $tag = PostTag::create( $tag_name, Inflector::slug( $tag_name, '_' ), $form->type_id );
				        $this->tags->save( $tag );
			        }
			        $post->assignTag( $tag->id );
		        }
	        }
            $this->posts->save($post);
        });

        return $post;
    }

    public function edit($id, PostForm $form): void
    {
        $post = $this->posts->get($id);
        $category = $this->categories->get($form->category_id);

        $post->edit(
            $category->id,
            $form->title,
            $form->slug,
            $form->description,
            $form->content,
            $form->published_at,
            $form->video,
            new Meta(
                $form->meta->title,
                $form->meta->description,
                $form->meta->keywords
            )
        );

        if ($form->image) {
	        $post->cleanFiles();
            $post->setImage($form->image);
        }
	    elseif ($form->video && (!$post->image || $form->reset_image)) {
		    $post->cleanFiles();
			$src = 'https://i.ytimg.com/vi/' . PostHelper::parseYoutubeUrl($post->video) . '/maxresdefault.jpg';
			$filename = (new Security())->generateRandomString(15) . '.jpg';
			copy($src, \Yii::getAlias(Post::FILE_ORIGINAL_PATH . '/' . $post->id . '.jpg'));
			$post->image = $filename;
		}
		elseif ($post->image && $form->reset_image) {
        	$post->cleanFiles();
        	//Post::updateAll(['image' => null], ['id' => $post->id]);
			$post->image = null;
			$post->updateAttributes(['image']);
		}

        $this->transaction->wrap(function () use ($post, $form) {
            $post->revokeTags();
            $this->posts->save($post);

            $tag_updated = false;
            if (is_array($form->tags->new_tags) && !empty($form->tags->new_tags)) {
	            foreach ( $form->tags->new_tags as $tag_id => $tag_name ) {
		            if ( ! $tag = $this->tags->findByName( $tag_name, $form->type_id ) ) {
			            $tag = PostTag::create( $tag_name, Inflector::slug( $tag_name, '_' ), $form->type_id );
			            $this->tags->save( $tag );
		            }
		            $post->assignTag( $tag->id );
		            $tag_updated = true;
	            }
            }

            if ($tag_updated) {
	            $this->posts->save( $post );
            }
        });
    }

    public function activate($id): void
    {
        $post = $this->posts->get($id);
        $post->activate();
        $this->posts->save($post);
    }

    public function draft($id): void
    {
        $post = $this->posts->get($id);
        $post->draft();
        $this->posts->save($post);
    }

    public function remove($id): void
    {
        $post = $this->posts->get($id);
        $this->posts->remove($post);
    }
}