<?php

namespace App\Http\Controllers\Dashboard;

use App\Helpers\Alert;
use App\Http\Requests\Dashboard\PostRequest;
use App\Models\Tag;
use App\Models\Post;
use App\Models\User;
use App\Models\Category;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Mews\Purifier\Facades\Purifier;
use App\Http\Controllers\Controller;
use App\Notifications\PostConfirmed;
use Illuminate\Support\Facades\File;
use App\Notifications\NewPostCreated;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Notification;

class PostsController extends Controller
{
    public function index()
    {
        if (auth()->user()->hasPermission("access_all_posts")) $posts = Post::all();
        else $posts = Post::where("user_id", auth()->user()->id)->get();

        return view("dashboard.posts.index")->with([
            "posts" => $posts,
            "currentUser" => auth()->user()
        ]);
    }

    public function create()
    {
        return view("dashboard.posts.create")->with([
            "categories" => Category::all(),
            "tags" => Tag::all()
        ]);
    }

    public function editShow($id)
    {
        $post = Post::findOrFail($id);

        if (!auth()->user()->hasPermission("edit_all_posts") && ($post->user->id != auth()->user()->id || !$post->is_confirmed)) {
            return redirect()->route("dashboard.posts.index");
        }

        return view("dashboard.posts.edit")->with([
            "post" => $post,
            "postTags" => $post->tag()->pluck("id")->toArray(),
            "categories" => Category::all(),
            "tags" => Tag::all()
        ]);
    }

    public function edit(PostRequest $request, $id)
    {
        $post = Post::findOrFail($id);

        $category = Category::find($request->category);

        $post->category()->associate($category);

        $post->title = $request->title;

        if ($request->hasFile("image")) {

            Storage::disk('uploads')->delete($post->image_link);

            $image = $request->file("image");
            $extension = $image->getClientOriginalExtension();
            $imageName = $this->createImageName($extension);
            Storage::disk('uploads')->put($imageName, File::get($image));

            $post->image_link = $imageName;
        }

        $post->content = clean($request->post_content);
        $post->slug = $post->createSlug(true);

        $post->save();
        $this->checkNewAndSaveTags($post, $request->tags, true);

        Alert::flash("Post edited successfully");

        return redirect()->route("dashboard.posts.index");
    }

    public function store(PostRequest $request)
    {
        $post = new Post();
        $user = auth()->user();
        $category = Category::find($request->category);

        $post->user()->associate($user);
        $post->category()->associate($category);

        $post->title = $request->title;

        $image = $request->file("image");
        $extension = $image->getClientOriginalExtension();
        $imageName = $this->createImageName($extension);
        Storage::disk('uploads')->put($imageName, File::get($image));

        $post->image_link = $imageName;
        $post->content = Purifier::clean($request->post_content, 'youtube');

        $post->slug = $post->createSlug();

        if ($post->user->hasPermission("publish_post")) {
            $post->confirmed_by = $post->user->id;
            $post->is_active = 1;
            $post->is_confirmed = true;
        }

        $post->save();
        $this->checkNewAndSaveTags($post, $request->tags);

        if ($post->user->hasPermission("publish_post")) {
            Alert::flash("New posts published successfully");
        } else {
            Alert::flash("New posts submitted for review successfully");
            $adminsAndEditors = User::where("role_id", 1)->orWhere("role_id", 2)->get();
            Notification::send($adminsAndEditors, new NewPostCreated("Have new post for review"));
        }

        return redirect()->route("dashboard.posts.create");
    }

    public function confirm(Request $request, $id)
    {
        $post = Post::find($id);
        $flag = false;

        if (auth()->user()->hasPermission("confirm_post")) {
            $flag = true;
        }

        if ($flag) {

            $post->is_confirmed = true;
            $post->confirmed_by = auth()->user()->id;

            $post->save();

            Alert::flash("Post confirmed successfully");

            $post->user->notify(new PostConfirmed("Your post has been confirmed"));
        }

        return redirect()->route("dashboard.posts.index");
    }

    public function block(Request $request, $id)
    {
        $post = Post::find($id);
        $flag = false;

        if (auth()->user()->hasPermission("edit_all_posts")) {
            $flag = true;
        } else if ($post->is_active && auth()->user()->id == $post->user->id) {
            $flag = true;
        }

        if ($flag) {
            $post->is_active = false;
            $post->save();
            Alert::flash("Post blocked successfully");
        }

        return redirect()->route("dashboard.posts.index");
    }

    public function unblock(Request $request, $id)
    {
        $post = Post::find($id);
        $flag = false;

        if (auth()->user()->hasPermission("edit_all_posts")) {
            $flag = true;
        } else if (!$post->is_active && auth()->user()->id == $post->user->id) {
            $flag = true;
        }

        if ($flag) {
            $post->is_active = true;
            $post->save();
            Alert::flash("Post unblocked successfully.");
        }

        return redirect()->route("dashboard.posts.index");
    }

    public function destroy(Request $request, $id)
    {
        $post = Post::find($id);
        $flag = false;

        if (auth()->user()->hasPermission("delete_all_posts")) {
            $flag = true;
        } else if ($post->is_confirmed && auth()->user()->id == $post->user->id) {
            $flag = true;
        }

        if ($flag) {
            $usedTags = $post->tag->pluck("id")->toArray();
            $post->tag()->detach($usedTags);
            $post->delete();
            Storage::disk('uploads')->delete($post->image_link);
            Alert::flash("Post deleted successfully.");
        }

        return redirect()->route("dashboard.posts.index");
    }

    private function checkNewAndSaveTags(Post $post, $tags, $isEdit = false)
    {
        $tagsArray = explode(",", $tags);
        $ids = array();

        foreach ($tagsArray as $t) {

            $isNewTag = false;

            if (!is_numeric($t)) {

                $isNewTag = true;

                $tag = new Tag();
                $tag->name = strtolower(trim($t));

                if (strlen($tag->name) > 0) {
                    $tag->save();
                }
            }

            if ($isNewTag) {
                array_push($ids, $tag->id);
            } else {
                array_push($ids, $t);
            }
        }

        if ($isEdit) {
            $post->tag()->sync($ids);
        } else {
            $post->tag()->attach($ids);
        }
    }

    private function createImageName($extension)
    {
        return Str::random(10) . "." . $extension;
    }
}
