<?php

namespace App\Repositories\Backend\Blogs;

use App\Repositories\BaseRepository;
use App\Exceptions\GeneralException;
use App\Models\Blogs\Blog;
use App\Models\BlogMapCategories\BlogMapCategory;
use App\Models\BlogMapTags\BlogMapTag;
use Illuminate\Database\Eloquent\Model;
use App\Events\Backend\Blogs\BlogCreated;
use App\Events\Backend\Blogs\BlogDeleted;
use App\Events\Backend\Blogs\BlogUpdated;
use App\Http\Utilities\FileUploads;
use DB;
use Carbon\Carbon;

/**
 * Class BlogsRepository.
 */
class BlogsRepository extends BaseRepository
{
    /**
     * Associated Repository Model.
     */
    const MODEL = Blog::class;

    /**
     * @return mixed
     */
    public function getForDataTable()
    {
        return $this->query()
            ->leftjoin(config('access.users_table'),config('access.users_table').'.id','=',config('access.blogs_table').'.created_by')
            ->select([
                config('access.blogs_table').'.id',
                config('access.blogs_table').'.name',
                config('access.blogs_table').'.publish_datetime',
                config('access.blogs_table').'.status',
                config('access.blogs_table').'.created_by',
                config('access.blogs_table').'.created_at',
                config('access.users_table').'.first_name as user_name',
            ]);
    }

    /**
     * @param array $input
     * @param array $tagsArray
     * @param array $categoriesArray
     *
     * @throws GeneralException
     *
     * @return bool
     */
    public function create(array $input, array $tagsArray, array $categoriesArray)
    {
        // dd(Carbon::createFromFormat('d/m/Y h:i a',$input['publish_datetime']));
        DB::transaction(function () use ($input, $tagsArray, $categoriesArray) {
            $blogs = self::MODEL;
            $blogs = new $blogs();
            $blogs->name = $input['name'];
            $blogs->slug = str_slug($input['name']);
            $blogs->content = $input['content'];
            $blogs->publish_datetime = Carbon::parse($input['publish_datetime']);

            // Image Upload
            $image = $this->uploadImage($input);
            $blogs->featured_image = $image['featured_image'];
            
            $blogs->meta_title = $input['meta_title'];
            $blogs->cannonical_link = $input['cannonical_link'];
            $blogs->meta_keywords = $input['meta_keywords'];
            $blogs->meta_description = $input['meta_description'];
            $blogs->status = $input['status'];
            $blogs->created_by = access()->user()->id;

            if ($blogs->save()) {
                // Inserting associated category's id in mapper table
                for($i=0;$i<sizeof($categoriesArray);$i++)
                {
                    $blogMapCategory[] = [
                        "blog_id" => $blogs->id,
                        "category_id" => $categoriesArray[$i],
                    ];
                    
                }

                BlogMapCategory::insert($blogMapCategory);

                // Inserting associated tag's id in mapper table
                for($i=0;$i<sizeof($tagsArray);$i++)
                {
                    $blogMapTags[] = [
                        "blog_id" => $blogs->id,
                        "tag_id" => $tagsArray[$i],
                    ];
                }
                
                BlogMapTag::insert($blogMapTags);
                
                event(new BlogCreated($blogs));
                return true;
            }
            throw new GeneralException(trans('exceptions.backend.blogs.create_error'));
        });
    }

    /**
     * @param Model $permission
     * @param  $input
     *
     * @throws GeneralException
     *
     * return bool
     */
     
    public function update(Model $blogs, array $input, array $tagsArray, array $categoriesArray)
    {
        // dd( Carbon::parse($input['publish_datetime']));
        // dd($input['publish_datetime']);
        $blogs->name = $input['name'];
        $blogs->slug = str_slug($input['name']);
        $blogs->content = $input['content'];
        $blogs->publish_datetime = Carbon::parse($input['publish_datetime']);
        $blogs->meta_title = $input['meta_title'];
        $blogs->cannonical_link = $input['cannonical_link'];
        $blogs->meta_keywords = $input['meta_keywords'];
        $blogs->meta_description = $input['meta_description'];
        $blogs->status = $input['status'];
        $blogs->updated_by = access()->user()->id;

        // Uploading Image
        if(array_key_exists('featured_image',$input))
        {
            $this->deleteOldFile($blogs);
            $input = $this->uploadImage($input);
            $blogs->featured_image = $input['featured_image'];
        }

        DB::transaction(function () use ($blogs, $input, $tagsArray, $categoriesArray) {
        	if ($blogs->save()) {
                
                // Updateing associated category's id in mapper table
                BlogMapCategory::where("blog_id", $blogs->id)->delete();
                for($i=0;$i<sizeof($categoriesArray);$i++)
                {
                    $blogMapCategory[] = [
                        "blog_id" => $blogs->id,
                        "category_id" => $categoriesArray[$i],
                    ];
                    
                }

                BlogMapCategory::insert($blogMapCategory);

                // Updating associated tag's id in mapper table
                BlogMapTag::where("blog_id", $blogs->id)->delete();
                for($i=0;$i<sizeof($tagsArray);$i++)
                {
                    $blogMapTags[] = [
                        "blog_id" => $blogs->id,
                        "tag_id" => $tagsArray[$i],
                    ];
                }
                
                BlogMapTag::insert($blogMapTags);
                
                event(new BlogUpdated($blogs));

                return true;
            }

            throw new GeneralException(
                trans('exceptions.backend.blogs.update_error')
            );
        });
    }

    /**
     * @param Model $blog
     *
     * @throws GeneralException
     *
     * @return bool
     */
    public function delete(Model $blog)
    {
        DB::transaction(function () use ($blog) {

            if ($blog->delete()) {
                BlogMapCategory::where("blog_id", $blog->id)->delete();
                BlogMapTag::where("blog_id", $blog->id)->delete();
                
                event(new BlogDeleted($blog));
                return true;
            }

            throw new GeneralException(trans('exceptions.backend.blogs.delete_error'));
        });
    }

    /**
     * Upload Image
     *
     * @param Array $input
     * @return Array $input
     */
    public function uploadImage($input)
    {
        $uploadManager = new FileUploads;
        $avatar = $input['featured_image'];

        if(isset($input['featured_image']) && !empty($input['featured_image']))
        {
            $fileName = $uploadManager->setBasePath("backend/blog_images")
                ->setThumbnailFlag(false)
                ->upload($input['featured_image']);

            $input = array_merge($input, [ 'featured_image' => $fileName]);

            return $input;
            
        }            
    }

    /**
     * Destroy Old Image
     *
     * @param int $id
     */
    public function deleteOldFile($model)
    {
        $uploadManager = new FileUploads;
        $fileName   = $model->featured_image;
        $filePath   = $uploadManager->setBasePath("backend/blog_images");
        $file       = $filePath->filePath.DIRECTORY_SEPARATOR.$fileName;
        
        return $uploadManager->deleteFile($file);
    }
}