<?php

namespace App\Http\Controllers\Front;

use App\Http\Controllers\Controller;
use App\Models\Post;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use GrahamCampbell\Markdown\Facades\Markdown;
use Illuminate\Http\Request;
use JsonLd\Context;
use Symfony\Component\DomCrawler\Crawler;

class FrontPostController extends Controller
{
    public function redirect(Request $request, $slug)
    {
        $post = Post::where('slug', $slug)->where('status', 'publish')->first();

        if (is_null($post)) {
            return abort(404);
        }

        return redirect()->route('front.post',['category_slug' => $post->category->slug, 'slug' => $post->slug]);

    }

    public function index(Request $request, $category_slug, $slug)
    {
        $post = Post::where('slug', $slug)->where('status', 'publish')->first();

        if (is_null($post)) {
            return abort(404);
        }

        $content = Markdown::convert($post->body)->getContent();

        //dd($content);
        $content = $this->injectTableOfContents($content);
        $content = $this->injectBootstrapClasses($content);
        $content = $this->injectFeaturedImage($post, $content);
        $content = $this->injectPublishDateAndAuthor($post, $content);

        $post_description = $post->excerpt.' '.$post->title.' by EchoScoop.';

        // Generate breadcrumb data
        $breadcrumbs = collect([
            ['name' => 'Home', 'url' => route('front.home')],
        ]);

        if ($post->category) {
            foreach ($post->category->ancestors as $ancestor) {
                $breadcrumbs->push([
                    'name' => $ancestor->name,
                    'url' => route('front.category', $ancestor->slug),
                ]);
            }

            $breadcrumbs->push([
                'name' => $post->category->name,
                'url' => route('front.category', $post->category->slug),
            ]);
        }

        $breadcrumbs->push([
            'name' => $post->title,
            'url' => url()->current(),  // The current page URL; the breadcrumb is not clickable
        ]);

        SEOMeta::setTitle($post->title, false);
        SEOMeta::setDescription($post_description);
        SEOMeta::addMeta('article:published_time', $post->published_at->format('Y-m-d'), 'property');
        SEOMeta::addMeta('article:section', $post->category->name, 'property');
        SEOMeta::setRobots('INDEX, FOLLOW, MAX-IMAGE-PREVIEW:LARGE, MAX-SNIPPET:-1, MAX-VIDEO-PREVIEW:-1');

        OpenGraph::setDescription($post_description);
        OpenGraph::setTitle($post->title);
        OpenGraph::setUrl(url()->current());
        OpenGraph::addProperty('type', 'article');
        OpenGraph::addProperty('locale', 'en_US');
        OpenGraph::addImage($post->featured_image_cdn);

        $jsonld_multi = JsonLdMulti::newJsonLd();
        $jsonld_multi->setTitle($post->title)
            ->setDescription($post_description)
            ->setType('Article')
            ->addValue('headline', $post->title)
            ->addImage($post->featured_image_cdn)
            ->addValue('author', [
                'type' => 'Person',
                'name' => $post->author->name,
                'url' => config('app.url'),
            ])
            ->addValue('publisher', [
                'type' => 'Organization',
                'name' => 'EchoScoop',
                'logo' => [
                    'type' => 'ImageObject',
                    'url' => asset('echoscoop-logo-512x512.png'),
                ],
            ])
            ->addValue('datePublished', $post->published_at->format('Y-m-d'))
            ->addValue('dateCreated', $post->created_at->format('Y-m-d'))
            ->addValue('dateModified', $post->updated_at->format('Y-m-d'))
            ->addValue('description', $post_description)
            ->addValue('articleBody', trim(preg_replace('/\s\s+/', ' ', strip_tags($content))));

        // breadcrumb json ld
        $listItems = [];

        foreach ($breadcrumbs as $index => $breadcrumb) {
            $listItems[] = [
                'name' => $breadcrumb['name'],
                'url' => $breadcrumb['url'],
            ];
        }

        $breadcrumb_context = Context::create('breadcrumb_list', [
            'itemListElement' => $listItems,
        ]);

        return view('front.single_post', compact('post', 'content', 'breadcrumbs', 'breadcrumb_context'));
    }

    private function injectBootstrapClasses($content)
    {
        $crawler = new Crawler($content);

        // Handle Headings
        $crawler->filter('h1')->each(function (Crawler $node) {
            $node->getNode(0)->setAttribute('class', trim($node->attr('class').' display-6 fw-bolder mt-3 mb-2'));
        });

        $crawler->filter('h2')->each(function (Crawler $node) {
            $node->getNode(0)->setAttribute('class', trim($node->attr('class').' h4 mb-3'));
        });

        $crawler->filter('h3')->each(function (Crawler $node) {
            $node->getNode(0)->setAttribute('class', trim($node->attr('class').' h6 mb-3'));
        });

        // Handle Paragraphs
        $crawler->filter('p')->each(function (Crawler $pNode) {
            $precedingHeaders = $pNode->previousAll()->filter('h2');

            if (! $precedingHeaders->count()) {
                $existingClasses = $pNode->attr('class');
                $newClasses = trim($existingClasses.' mt-2 mb-4');
                $pNode->getNode(0)->setAttribute('class', $newClasses);

                return;
            }

            $precedingHeader = $precedingHeaders->first();
            if (trim($precedingHeader->text()) !== 'FAQs') {
                $existingClasses = $pNode->attr('class');
                $newClasses = trim($existingClasses.' mt-2 mb-4');
                $pNode->getNode(0)->setAttribute('class', $newClasses);
            }

            if (strpos($pNode->text(), 'Q:') === 0) {
                $currentClasses = $pNode->attr('class');
                $newClasses = trim($currentClasses.' fw-bold');
                $pNode->getNode(0)->setAttribute('class', $newClasses);
            }
        });

        // Handle Lists
        $crawler->filter('ul')->each(function (Crawler $node) {
            $node->getNode(0)->setAttribute('class', trim($node->attr('class').' py-2'));
        });

        $crawler->filter('ol')->each(function (Crawler $node) {
            $node->getNode(0)->setAttribute('class', trim($node->attr('class').' py-2'));
        });

        // Handle Tables
        $crawler->filter('table')->each(function (Crawler $node) {
            $node->getNode(0)->setAttribute('class', trim($node->attr('class').' table table-bordered mb-4'));
        });

        // Convert the modified DOM back to string
        $modifiedContent = '';
        foreach ($crawler as $domElement) {
            $modifiedContent .= $domElement->ownerDocument->saveHTML($domElement);
        }

        return $modifiedContent;
    }

    private function injectTableOfContents($html)
    {
        $crawler = new Crawler($html);

        $h2Elements = $crawler->filter('h2');

        if ($h2Elements->count() < 3) {
            // Return the original HTML if there are fewer than 3 h2 tags
            return $html;
        }

        // Create the Table of Contents
        $domDocument = $crawler->getNode(0)->ownerDocument;
        $tocDiv = $domDocument->createElement('div');
        $tocDiv->setAttribute('class', 'p-3 rounded-3 bg-light mb-3');
        $ol = $domDocument->createElement('ol');
        $tocDiv->appendChild($ol);

        $h2Elements->each(function (Crawler $node, $i) use ($ol) {
            $content = htmlspecialchars($node->text(), ENT_XML1 | ENT_COMPAT, 'UTF-8');
            $id = 'link-'.$i;
            $node->getNode(0)->setAttribute('id', $id);
            $li = $ol->appendChild(new \DOMElement('li'));
            $li->setAttribute('class', 'py-1');
            $a = $li->appendChild(new \DOMElement('a', $content));
            $a->setAttribute('class', 'text-decoration-none hover-text-decoration-underline');
            $a->setAttribute('href', '#'.$id);
        });

        // Insert TOC after h1
        $h1Node = $crawler->filter('h1')->getNode(0);
        $h1Node->parentNode->insertBefore($tocDiv, $h1Node->nextSibling);

        // Get the updated HTML
        $updatedHtml = $crawler->filter('body')->html();

        return $updatedHtml;
    }

    private function injectPublishDateAndAuthor($post, $content)
    {
        $publishedAtFormatted = $post->published_at->format('F j, Y');
        $authorName = $post->author->name;

        // Create the HTML structure for publish date and author
        $publishInfo = "<div class=\"mb-4\"><span class=\"text-secondary small\">Published on {$publishedAtFormatted} by {$authorName}</span></div>";

        // Inject the publish date and author information after the `h1` tag
        $content = preg_replace('/(<\/h1>)/', '$1'.$publishInfo, $content, 1);

        return $content;
    }

    private function injectFeaturedImage($post, $content)
    {
        if (! empty($post->featured_image)) {
            $featured_image_alt = strtolower($post->short_title);
            $featured_image_alt_caps = strtoupper($post->short_title);

            // Update the HTML structure
            $featured_image = "<div class=\"w-100 d-flex justify-content-center\"><figure class=\"text-center\"><img decoding=\"async\" class=\"img-fluid rounded mb-2 shadow lqip-blur\" src=\"{$post->featured_image_lqip_cdn}\" data-src=\"{$post->featured_image_cdn}\" alt=\"{$featured_image_alt}\"><figcaption class=\"text-secondary small\">{$featured_image_alt_caps}</figcaption></figure></div>";

            $content = preg_replace('/(<\/h1>)/', '$1'.$featured_image, $content, 1);
        }

        return $content;
    }
}
