<?php

namespace App\Services\Blog\Articles;

use App\Models\Article;
use App\Models\ArticleComment;
use App\Models\Setting;
use Illuminate\Support\Facades\Cache;

class ArticleService
{
    /** 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 random article */
    public function getRandomArticles(Article $article)
    {
        return Article::where('status', 'publish')->where('id', '!=', $article->id)->inRandomOrder()->limit(6)->get()->map(fn($article) => [
            'id' => $article->id,
            'title' => $article->title,
            'slug' => $article->slug,
            'get_image' => $article->get_image,
            'get_formatted_view_count' => $article->get_formatted_view_count,
            'jalali_created_at' => $article->jalali_created_at,
            'user' => $article->get_user,
            'category' => $article->get_category,
        ]);
    }

    /** get latest article */
    public function getLatestArticles(Article $article)
    {
        return Article::where('status', 'publish')->where('id', '!=', $article->id)->orderBy('created_at', 'desc')->take(12)->get()->map(fn($article) => [
            'id' => $article->id,
            'title' => $article->title,
            'slug' => $article->slug,
            'get_image' => $article->get_image,
            'get_formatted_view_count' => $article->get_formatted_view_count,
            'jalali_created_at' => $article->jalali_created_at,
            'user' => $article->get_user,
            'category' => $article->get_category,
        ]);
    }

    /** get article comments */
    public function getArticleComments(Article $article)
    {
        $comments = $article->articleComments()->where('status', 'publish')->where('reply_to', null)->orderBy('created_at', 'desc')->paginate(6, ['*'], 'cpage')->through(fn($comment) => [
            'id' => $comment->id,
            'content' => $comment->content,
            'reply_to' => $comment->reply_to,
            'vote_up' => $comment->vote_up,
            'vote_down' => $comment->vote_down,
            'status' => $comment->status,
            'jalali_created_at' => $comment->jalali_created_at,
            'get_reply_to' => null,
            'answers' => Cache::remember('comment_answers_' . $comment->id, now()->addMonth(), function () use ($comment) {
                return ArticleComment::where('status', 'publish')->where('reply_to', $comment->id)->orderBy('created_at', 'asc')->get();
            })->map(fn($c) => [
                'id' => $c->id,
                'content' => $c->content,
                'reply_to' => $c->reply_to,
                'vote_up' => $c->vote_up,
                'vote_down' => $c->vote_down,
                'status' => $c->status,
                'jalali_created_at' => $c->jalali_created_at,
                'get_reply_to' => $c->get_reply_to != null ? [
                    'user' => [
                        'id' => $c->get_reply_to['user']['id'],
                        'get_name' => $c->get_reply_to['user']['get_name'],
                        'username' => $c->get_reply_to['user']['username'],
                        'get_avatar' => $c->get_reply_to['user']['get_avatar'],
                    ],
                ] : null,
                'answers' => null,
                'user' => $c->get_user
            ]),
            'user' => $comment->get_user
        ]);
        $comments->withQueryString();

        return $article->comment_status ? $comments : [];
    }

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

        // schema
        $this->seo['schema'] = $this->articleSchema($article);

        // main
        $this->seo['site_name'] = $blogName;
        $this->seo['title'] = ($article->seo_title != null ? $article->seo_title : $article->title);
        $this->seo['description'] = $article->seo_description;
        $this->seo['keywords'] = $article->get_seo_keywords;
        $this->seo['canonical'] = $article->seo_canonical;
        $this->seo['author'] = $article->user->store != null ? $article->user->store->name : $article->user->name;
        $this->seo['image'] = $article->get_image['url'];
        $this->seo['type'] = 'article';

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

    /** Product Schema */
    public function articleSchema(Article $article)
    {
        $blogName = Cache::remember('setting_blog_title', now()->addMonth(), function () {
            return Setting::where('key', 'blog_title')->first() != null ? Setting::where('key', 'blog_title')->first()->value : null;
        });

        $articleSchema =  [
            "@context" => "https://schema.org",
            "@type" => "Article",
            "name" => $article->title,
            "alternateName" => $article->title_en,
            "headline" => $article->title,
            "image" => $article->get_image['url'],
            "description" => $article->seo_description,
            "articleSection" => $article->articleCategory->title,
            "datePublished" => $article->created_at,
            "dateModified" => $article->updated_at,
            "author" => [
                "@type" => "Person",
                "url" => urldecode(route('blog.articles.index', ['profile' => $article->user->store != null ? $article->user->store->uuid : $article->user->username])),
                "name" => $article->user->store != null ? $article->user->store->name : $article->user->name
            ],
            "interactionStatistic" => [
                "@type" => "InteractionCounter",
                "interactionType" => [
                    "@type" => "LikeAction"
                ],
                "userInteractionCount" => $article->vote > 0 ? $article->vote : 1
            ]
        ];

        if ($article->articleComments()->count() > 0) {
            $lastReview = $article->articleComments()->where('status', 'publish')->orderBy('created_at', 'desc')->first();
            if ($lastReview != null) {
                $articleSchema["review"] = [
                    "@type" => "Review",
                    "author" => [
                        "@type" => "Person",
                        "name" => $lastReview->user->name,
                    ],
                    "datePublished" => $lastReview->created_at,
                    "reviewBody" => $lastReview->content,
                    "itemReviewed" => [
                        "@type" => "Product",
                        "name" => $article->title
                    ]
                ];
            }
        }

        $breadcrumbSchema = [
            "@context" => "https://schema.org",
            "@type" => "BreadcrumbList",
            "itemListElement" => [
                [
                    "@type" => "ListItem",
                    "position" => 1,
                    "name" => $blogName,
                    "item" => urldecode(route('blog.index'))
                ],
                [
                    "@type" => "ListItem",
                    "position" => 2,
                    "name" => $article->articleCategory->title,
                    "item" => urldecode(route('blog.articles.index', ['cat' => $article->articleCategory->slug]))
                ],
                [
                    "@type" => "ListItem",
                    "position" => 3,
                    "name" => $article->title,
                    "item" => urldecode(route('blog.articles.show', $article->slug))
                ]
            ],
        ];

        return [
            'article' => json_encode($articleSchema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
            'breadcrumb' => json_encode($breadcrumbSchema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
        ];
    }
}
