<?php

namespace App\Services\Blog;

use App\Models\Article;
use App\Models\ArticleCategory;
use App\Models\ArticleTag;
use App\Models\Setting;
use Illuminate\Support\Facades\Cache;

class BlogService
{
    /** seo meta data */
    public array $seo = [
        'schema' => null,
        'site_name' => null,
        'title' => null,
        'store_name' => null,
        'description' => null,
        'keywords' => null,
        'canonical' => null,
        'author' => null,
        'image' => null,
        'type' => null,
    ];

    /** get components with data */
    public function getComponents($template)
    {
        if ($template != null) {
            $components = $template->get_blog_data['index'];

            foreach ($template->get_blog_data['index'] as $key => $component) {
                if (array_key_exists("category_list", $component["data"])) {
                    @$components[$key]["data"]["category_list"]["categories"] = $this->getCategoryLists()[$component["data"]["category_list"]["id"]];
                }
                if (array_key_exists("article_list", $component["data"])) {
                    @$components[$key]["data"]["article_list"]["articles"] = $this->getArticleLists($component);
                }
                if (array_key_exists("hashtags", $component["data"])) {
                    @$components[$key]["data"]["hashtags"] = $this->getHashtags();
                }
            }

            return $components;
        } else {
            return [];
        }
    }

    /** get article category lists */
    public function getCategoryLists()
    {
        $categories['simple_list'] = Cache::remember('blog_category_simple_list', now()->addMonth(), function () {
            return ArticleCategory::where('status', 'publish')->inRandomOrder()->limit(12)->get()->map(fn($category) => [
                'id' => $category->id,
                'title' => $category->title,
                'slug' => $category->slug,
                'get_image' => $category->get_image,
                'get_last_article_image' => $category->get_last_article_image,
            ]);
        });

        return $categories;
    }

    /** get article lists */
    public function getArticleLists($component)
    {
        $finalArticle = [];

        // custom articles list
        $articles['latest_articles'] = Article::where('status', 'publish')->orderBy('created_at', 'desc');
        $articles['random_articles'] = Article::where('status', 'publish')->inRandomOrder();
        $articles['editor_choice_articles'] = Article::where('status', 'publish')->where('editor_choice', true)->orderBy('created_at', 'desc');
        $articles['most_viewed_articles'] = Article::where('status', 'publish')->orderBy('view_count', 'desc');

        // add articles data to template components
        if (in_array('article_list', $component['type'])) {
            if (count($component['data']['article_list']) > 0) {
                $itemCount = 6;

                if (is_int($component['data']['article_list']['id'])) {
                    // category based article list
                    $finalArticle = Article::where('status', 'publish')
                        ->where('category_id', $component['data']['article_list']['id'])
                        ->orderBy('created_at', 'desc')
                        ->take($itemCount)
                        ->get()
                        ->map(fn($article) => [
                            'id' => $article->id,
                            'title' => $article->title,
                            'slug' => $article->slug,
                            'get_image' => $article->get_image,
                            'jalali_created_at' => $article->jalali_created_at,
                            'get_formatted_view_count' => $article->get_formatted_view_count,
                            'seo_description' => $article->seo_description,
                            'type' => $article->type,

                            'user' => $article->get_user,
                            'category' => $article->get_category,
                        ]);
                } else {
                    // choose from custom articles list
                    $finalArticle = $articles[$component['data']['article_list']['id']]
                        ->limit($itemCount)
                        ->get()
                        ->map(fn($article) => [
                            'id' => $article->id,
                            'title' => $article->title,
                            'slug' => $article->slug,
                            'get_image' => $article->get_image,
                            'jalali_created_at' => $article->jalali_created_at,
                            'get_formatted_view_count' => $article->get_formatted_view_count,
                            'seo_description' => $article->seo_description,
                            'type' => $article->type,

                            'user' => $article->get_user,
                            'category' => $article->get_category,
                        ]);
                }
            }
        }

        return $finalArticle;
    }

    /** get article hashtag list */
    public function getHashtags()
    {
        $hashtags = Cache::remember('get_hashtags', now()->addMonth(), function () {
            return ArticleTag::where('status', 'publish')->orderBy('view_count', 'desc')->limit(18)->get()->map(fn($tag) => [
                'id' => $tag->id,
                'title' => $tag->title,
                'slug' => $tag->slug,
            ]);
        });

        return $hashtags;
    }

    /** seo information */
    public function seo()
    {
        $blogName = Cache::remember('setting_blog_title', now()->addMonth(), function () {
            $blogName = Setting::where('key', 'blog_title')->first();
            return $blogName != null ? $blogName->value : null;
        });
        $blogDescription = Cache::remember('setting_blog_description', now()->addMonth(), function () {
            $blogDescription = Setting::where('key', 'blog_description')->first();
            return $blogDescription != null ? $blogDescription->value : null;
        });

        // schema
        $this->seo['schema'] = $this->blogSchema($blogName);

        // main
        $this->seo['site_name'] = $blogName;
        $this->seo['title'] = $blogName;
        $this->seo['description'] = $blogDescription;

        // return information
        return $this->seo;
    }

    /** Blog Schema */
    public function blogSchema($blogName)
    {
        $email = Cache::remember('setting_support_email', now()->addMonth(), function () {
            $email = Setting::where('key', 'support_email')->first();
            return $email != null ? $email->value : null;
        });

        $phone = Cache::remember('setting_support_phone', now()->addMonth(), function () {
            $phone = Setting::where('key', 'support_phone')->first();
            return $phone != null ? $phone->value : null;
        });

        $address = Cache::remember('setting_shop_address', now()->addMonth(), function () {
            $address = Setting::where('key', 'shop_address')->first();
            return $address != null ? $address->value : null;
        });

        $geoLocation = Cache::remember('setting_shop_map_location', now()->addMonth(), function () {
            $geoLocation = Setting::where('key', 'shop_map_location')->first();
            return $geoLocation != null ? unserialize($geoLocation->value) : null;
        });

        $latestArticles = [];
        $articles = Article::where('status', 'publish')->orderBy('created_at', 'desc')->take(6)->get();
        foreach ($articles as $key => $article) {
            $latestArticles[] = [
                "@type" => "ListItem",
                "position" => $key + 1,
                "name" => $article->title,
                "url" => urldecode(route('blog.articles.show', $article->slug))
            ];
        }

        $schema = [
            [
                "@context" => "https://schema.org",
                "@type" => "WebSite",
                "id" => asset("/blog/#WebSite"),
                "name" => $blogName,
                "url" => route('blog.index'),
                "email" => $email,
                "contactPoint" => [
                    "@type" => "ContactPoint",
                    "telephone" => $phone,
                    "contactType" => "customer service",
                    "areaServed" => "IR",
                    "availableLanguage" => "Persian"
                ],
                "address" => [
                    "@type" => "PostalAddress",
                    "streetAddress" => $address,
                    "geo" => $geoLocation != null ? [
                        "@type" => "GeoCoordinates",
                        "latitude" => $geoLocation["latitude"],
                        "longitude" => $geoLocation["longitude"]
                    ] : null,
                    "addressCountry" => [
                        "@type" => "Country",
                        "name" => "Iran"
                    ]
                ],
                "copyrightHolder" => [
                    "@type" => "Organization",
                    "name" => $blogName
                ],
                "creator" => [
                    "@type" => "Organization",
                    "name" => $blogName,
                ],
            ],
            [
                "@context" => "https://schema.org",
                "@type" => "ItemList",
                "url" => route('blog.index'),
                "itemListElement" => $latestArticles
            ]
        ];

        return json_encode($schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    }
}
