<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Artesaos\SEOTools\Facades\SEOTools;
use Artesaos\SEOTools\Facades\SEOMeta;
use App\Models\Post;
use App\Models\Category;
use App\Models\User;
use App\Helpers\CMail;

class BlogController extends Controller
{
    /**
     * Zeigt die Startseite der Website an.
     *
     * ROUTE: /
     * METHOD: GET
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\View\View
    */
    public function index(Request $request) {

        $title = isset(settings()->site_title) ? settings()->site_title : '';
        $description = isset(settings()->site_meta_description) ? settings()->site_meta_description : '';
        $imgURL = isset(settings()->site_logo) ? asset('/images/site/'.settings()->site_logo) : '';
        $keywords = isset(settings()->site_meta_keywords) ? settings()->site_meta_keywords : '';
        $currentUrl = url()->current();

        /** 
         * META SEO
         */
        SEOTools::setTitle($title, false);
        SEOTools::setDescription($description);
        SEOMeta::setKeywords($keywords);

        /** 
         * OPEN GRAPH
         */
        SEOTools::opengraph()->setUrl($currentUrl);
        SEOTools::opengraph()->addImage($imgURL);
        SEOTools::opengraph()->addProperty('type', 'articles');
        
        /** 
         * TWITTER
         */
        SEOTools::twitter()->addImage($imgURL);
        SEOTools::twitter()->setUrl($currentUrl);
        SEOTools::twitter()->setSite('@larablog');

        $title = isset(settings()->site_title) ? settings()->site_title : '';
        $data = [
            'pageTitle' => $title
        ];

        return view('front.pages.index', $data);
    }
    /**
     * Gibt alle sichtbaren Blogbeiträge einer Kategorie aus.
     *
     * ROUTE: /category/{slug}
     * METHOD: GET
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string|null  $slug   Slug der Kategorie
     * @return \Illuminate\View\View
    */
    public function categoryPosts(Request $request, $slug = null) {
        $category = Category::where('slug', $slug)->firstOrFail();

        $posts = Post::where('category',  $category->id)->where('visibility',1)->paginate(8);

        $title = 'Posts in der Kategorie: '.$category->name;
        $description = 'Durchstöbern Sie die neuesten Beiträge in der Kategorie '.$category->name.'. Bleiben Sie mit Artikeln, Einblicken und Anleitungen auf dem Laufenden.';

        /** 
         * SEO
         */
        SEOTools::setTitle($title, false);
        SEOTools::setDescription($description);
        SEOTools::opengraph()->setUrl(url()->current());

        $data = [
            'pageTitle' => $category->name,
            'posts' => $posts
        ];

        return view('front.pages.category_posts', $data);
    }

    /**
     * Gibt alle sichtbaren Blogbeiträge eines Autors aus.
     *
     * ROUTE: /author/{username}
     * METHOD: GET
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string|null  $username   Benutzername des Autors
     * @return \Illuminate\View\View
    */
    public function authorPosts(Request $request, $username = null) {
        $author = User::where('username', $username)->firstOrFail();
        $posts = Post::where('author_id', $author->id)->where('visibility',1)->orderBy('created_at', 'asc')->paginate(8);
        $title = $author->name.' - Blog Posts';
        $description = 'Entdecke die neuesten Beiträge von .'.$author->name.' zu verschiedenen Themen';

        /** 
         * SEO
         */
        SEOTools::setTitle($title, false);
        SEOTools::setDescription($description);
        SEOTools::setCanonical(route('author_posts', ['username' => $author->username]));
        SEOTools::opengraph()->setUrl(route('author_posts', ['username' => $author->username]));
        SEOTools::opengraph()->addProperty('type', 'profile');
        SEOTools::opengraph()->setProfile([
            'first_name' => $author->name,
            'username' => $author->username
        ]);

        $data = [
            'pageTitle' => $author->name,
            'author' => $author,
            'posts' => $posts
        ];

        return view('front.pages.author_posts', $data);
    }

    /**
     * Gibt alle sichtbaren Blogbeiträge zu einem bestimmten Tag aus.
     *
     * ROUTE: /tag/{tag}
     * METHOD: GET
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string|null  $tag   Tag-Bezeichnung
     * @return \Illuminate\View\View
    */
    public function tagPosts(Request $request, $tag = null) {
        $posts = Post::where('tags', 'LIKE', "%{$tag}%")->where('visibility', 1)->paginate(8);

        $title = "Beiträge mit dem Tag '{$tag}'";
        $description = "Entdecke alle Beiträge in unserem Blog, die mit {$tag} getaggt sind.";


        /** 
         * SEO
         */
        SEOTools::setTitle($title, false);
        SEOTools::setDescription($description);
        SEOTools::setCanonical(url()->current());

        SEOTools::opengraph()->setUrl(url()->current());
        SEOTools::opengraph()->addProperty('type', 'articles');

        $data = [
            'pageTitle' => $title,
            'tag' => $tag,
            'posts' => $posts,
        ];

        return view('front.pages.tag_posts',  $data);
    }

    /**
     * Durchsucht Blogbeiträge anhand eines Suchbegriffs.
     *
     * ROUTE: /search
     * METHOD: GET
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\View\View
    */
    public function searchPosts(Request $request) {

        $query = $request->input('q');

        if($query) {
            $keywords = explode(' ', $query);
            $postsQuery = Post::query();

            foreach($keywords as $keyword) {
                $postsQuery->orWhere('title', 'LIKE', '%'.$keyword.'%')->orWhere('tags', 'LIKE', '%'.$keyword.'%');
            }
            $posts = $postsQuery->where('visibility', 1)->orderBy('created_at', 'desc')->paginate(10);

            $title = "Such Ergebnis für {$query}";
            $description = "Durchsuchen Sie die Suchergebnisse für {$query} auf unserem Blog.";
        } else {
            $posts = collect();

            $title = 'Suche';
            $description = "Suchen Sie auf unserer Website nach Blogbeiträgen.";
        }

        SEOTools::setTitle($title, false);
        SEOTools::setDescription($description);

        $data = [
            'pageTitle' => $title,
            'query' => $query,
            'posts' => $posts
        ];

        return view('front.pages.search_posts', $data);
    }
    
    /**
     * Gibt einen einzelnen Blogbeitrag anhand des Slugs aus.
     *
     * ROUTE: /post/{slug}
     * METHOD: GET
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string|null  $slug   Eindeutiger Slug des Beitrags
     * @return \Illuminate\View\View
    */
    public function readPost(Request $request, $slug = null) {
        $post = Post::where('slug', $slug)->firstOrFail();

        $relatedPosts = Post::where('category', $post->category)->where('id', '!=', $post->id)->where('visibility',  1)->take(3)->get();
        $nextPost = Post::where('id', '>', $post->id)->where('visibility', 1)->orderBy('id', 'asc')->first();
        $prevPost = Post::where('id', '<', $post->id)->where('visibility', 1)->orderBy('id', 'desc')->first();

        /**
         * SEO
         */
        $title = $post->title;
        $description = ($post->meta_description != '') ? $post->meta_description : words($post->content, 35);

        SEOTools::setTitle($title, false);
        SEOTools::setDescription($description);
        SEOTools::opengraph()->setUrl(route('read_post', ['slug' => $post->slug]));
        SEOTools::opengraph()->addProperty('type', 'article');
        SEOTools::opengraph()->addImage(asset('images/posts/'.$post->featured_image));
        SEOTools::twitter()->setImage(asset('images/posts/'.$post->featured_image));
        SEOMeta::addMeta('article:published_time', $post->created_at->toW3CString(), 'property');
        SEOMeta::addMeta('article:section', $post->category, 'property');

        $data = [
            'pageTitle' => $title,
            'post' => $post,
            'relatedPosts' => $relatedPosts,
            'nextPost' => $nextPost,
            'prevPost' => $prevPost
        ];

        return view('front.pages.single_post', $data);
    }

    /**
     * Zeigt die Kontaktseite an.
     *
     * ROUTE: /contact
     * METHOD: GET
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\View\View
    */
    public function contactPage(Request $request) {
        $title = "Kontaktiere uns";
        $description = "Sie hassen Formulare? Schreiben Sie uns eine E-Mail.";

        /**
         * SEO
         */
        SEOTools::setTitle($title, false);
        SEOTools::setDescription($description);

        return view('front.pages.contact');

    }

    /**
     * Verarbeitet das Kontaktformular und versendet eine E-Mail.
     *
     * ROUTE: /contact/send
     * METHOD: POST
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
    */
    public function sendEmail(Request $request) {
        $request->validate([
            'name' => 'required',
            'email' => 'required|email',
            'subject' => 'required',
            'message' => 'required',
        ], [
            'name.required' => 'Name wird benötigt',
            'email.required' => 'Email wird benötigt',
            'email.email' => 'Bitte gültige Email angeben',
            'subject.required' => 'Titel wird benötigt',
            'message.required' => 'Nachricht wird benötigt',
        ]);

        $siteInfo = settings();

        $data = [
            'name' => $request->name,
            'email' => $request->email,
            'message' => $request->message,
            'subject' => $request->subject
        ];

        $mail_body = view('email-templates.contact-message-template', $data);

        $mail_config = [
            'from_name' => config('services.mail.from_name'),
            'replyToAddress' => $request->email,
            'replyToName' => $request->name,
            'recipient_address' => $siteInfo->site_email,
            'recipient_name' => $siteInfo->site_title,
            'subject' => $request->subject,
            'body' => $mail_body
        ];  

        if(CMail::send($mail_config, true)) {
            return redirect()->back()->with("success", "E-Mail wurde gesendet");
        } else {
            return redirect()->back()->with("fail", "Leider ist etwas schief gegangen, bitte versuchen Sie es später wieder");
        }
    }
}
