<?php

namespace App\Services;

use App\Models\Discussion;
use App\Models\DiscussionTopic;
use App\Models\KnowledgeBaseQuestion;
use App\Models\KnowledgeBaseCategory;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;

/**
 * SEOService
 * 
 * Handles SEO optimization for the Knowledge Sharing module.
 * Provides methods for generating meta tags, sitemap data, and structured data.
 * 
 * @package App\Services
 */
class SEOService
{
    /**
     * Generate SEO metadata for a discussion.
     *
     * @param \App\Models\Discussion $discussion
     * @return array
     */
    public function generateDiscussionMetadata(Discussion $discussion): array
    {
        return [
            'title' => $discussion->seo_title,
            'description' => $discussion->seo_description,
            'keywords' => $discussion->meta_keywords ?? $this->extractKeywords($discussion->title . ' ' . $discussion->excerpt),
            'canonical_url' => $discussion->url,
            'og_type' => 'article',
            'og_title' => $discussion->title,
            'og_description' => $discussion->seo_description,
            'og_url' => $discussion->url,
            'twitter_card' => 'summary_large_image',
            'twitter_title' => $discussion->title,
            'twitter_description' => $discussion->seo_description,
            'article_published_time' => $discussion->created_at->toIso8601String(),
            'article_modified_time' => $discussion->updated_at->toIso8601String(),
            'article_author' => $discussion->user->name ?? 'Anonymous',
            'article_section' => $discussion->topic->name ?? 'General',
        ];
    }

    /**
     * Generate SEO metadata for a discussion topic.
     *
     * @param \App\Models\DiscussionTopic $topic
     * @return array
     */
    public function generateTopicMetadata(DiscussionTopic $topic): array
    {
        return [
            'title' => $topic->seo_title,
            'description' => $topic->seo_description,
            'keywords' => $topic->meta_keywords ?? $topic->name,
            'canonical_url' => $topic->url,
            'og_type' => 'website',
            'og_title' => $topic->name . ' - Discussion Topic',
            'og_description' => $topic->seo_description,
            'og_url' => $topic->url,
            'twitter_card' => 'summary',
            'twitter_title' => $topic->name,
            'twitter_description' => $topic->seo_description,
        ];
    }

    /**
     * Generate SEO metadata for a knowledge base question.
     *
     * @param \App\Models\KnowledgeBaseQuestion $question
     * @return array
     */
    public function generateQuestionMetadata(KnowledgeBaseQuestion $question): array
    {
        return [
            'title' => $question->seo_title,
            'description' => $question->seo_description,
            'keywords' => $question->meta_keywords ?? implode(', ', $question->tags ?? []),
            'canonical_url' => $question->url,
            'og_type' => 'article',
            'og_title' => $question->title,
            'og_description' => $question->seo_description,
            'og_url' => $question->url,
            'twitter_card' => 'summary_large_image',
            'twitter_title' => $question->title,
            'twitter_description' => $question->seo_description,
            'article_published_time' => $question->published_at?->toIso8601String(),
            'article_modified_time' => $question->updated_at->toIso8601String(),
            'article_author' => $question->user->name ?? 'Anonymous',
            'article_section' => $question->category->name ?? 'General',
            'article_tags' => $question->tags ?? [],
        ];
    }

    /**
     * Generate SEO metadata for a knowledge base category.
     *
     * @param \App\Models\KnowledgeBaseCategory $category
     * @return array
     */
    public function generateCategoryMetadata(KnowledgeBaseCategory $category): array
    {
        return [
            'title' => $category->seo_title,
            'description' => $category->seo_description,
            'keywords' => $category->meta_keywords ?? $category->name,
            'canonical_url' => $category->url,
            'og_type' => 'website',
            'og_title' => $category->name . ' - Knowledge Base',
            'og_description' => $category->seo_description,
            'og_url' => $category->url,
            'twitter_card' => 'summary',
            'twitter_title' => $category->name,
            'twitter_description' => $category->seo_description,
        ];
    }

    /**
     * Generate landing page SEO metadata.
     *
     * @param string $type 'discussions' or 'knowledge-base'
     * @return array
     */
    public function generateLandingPageMetadata(string $type): array
    {
        $config = [
            'discussions' => [
                'title' => 'Community Discussion Boards - Ask Questions, Share Knowledge',
                'description' => 'Join our community discussion boards. Ask questions, share your knowledge, and connect with others. Browse topics, participate in discussions, and learn from the community.',
                'keywords' => 'discussions, community, questions, answers, forum, knowledge sharing, help, support',
            ],
            'knowledge-base' => [
                'title' => 'Knowledge Base - FAQs, Guides, and Documentation',
                'description' => 'Explore our comprehensive knowledge base. Find answers to frequently asked questions, guides, tutorials, and documentation organized by categories.',
                'keywords' => 'knowledge base, FAQ, documentation, guides, tutorials, help center, how-to',
            ],
        ];

        $data = $config[$type] ?? $config['discussions'];

        return [
            'title' => $data['title'],
            'description' => $data['description'],
            'keywords' => $data['keywords'],
            'canonical_url' => url($type === 'discussions' ? '/discussions' : '/knowledge-base'),
            'og_type' => 'website',
            'og_title' => $data['title'],
            'og_description' => $data['description'],
            'twitter_card' => 'summary_large_image',
            'twitter_title' => $data['title'],
            'twitter_description' => $data['description'],
        ];
    }

    /**
     * Generate Schema.org structured data for a discussion.
     *
     * @param \App\Models\Discussion $discussion
     * @return array
     */
    public function generateDiscussionSchema(Discussion $discussion): array
    {
        $schema = [
            '@context' => 'https://schema.org',
            '@type' => 'DiscussionForumPosting',
            'headline' => $discussion->title,
            'description' => $discussion->seo_description,
            'url' => $discussion->url,
            'datePublished' => $discussion->created_at->toIso8601String(),
            'dateModified' => $discussion->updated_at->toIso8601String(),
            'author' => [
                '@type' => 'Person',
                'name' => $discussion->user->name ?? 'Anonymous',
            ],
            'interactionStatistic' => [
                '@type' => 'InteractionCounter',
                'interactionType' => 'https://schema.org/CommentAction',
                'userInteractionCount' => $discussion->reply_count,
            ],
            'mainEntityOfPage' => [
                '@type' => 'WebPage',
                '@id' => $discussion->url,
            ],
        ];

        if ($discussion->topic) {
            $schema['about'] = [
                '@type' => 'Thing',
                'name' => $discussion->topic->name,
            ];
        }

        return $schema;
    }

    /**
     * Generate Schema.org structured data for a knowledge base question.
     *
     * @param \App\Models\KnowledgeBaseQuestion $question
     * @return array
     */
    public function generateQuestionSchema(KnowledgeBaseQuestion $question): array
    {
        $schema = [
            '@context' => 'https://schema.org',
            '@type' => 'QAPage',
            'mainEntity' => [
                '@type' => 'Question',
                'name' => $question->title,
                'text' => strip_tags($question->content),
                'dateCreated' => $question->created_at->toIso8601String(),
                'author' => [
                    '@type' => 'Person',
                    'name' => $question->user->name ?? 'Anonymous',
                ],
                'answerCount' => $question->answer_count,
            ],
        ];

        // Add accepted answer if exists
        if ($question->acceptedAnswer) {
            $schema['mainEntity']['acceptedAnswer'] = [
                '@type' => 'Answer',
                'text' => strip_tags($question->acceptedAnswer->content),
                'dateCreated' => $question->acceptedAnswer->created_at->toIso8601String(),
                'author' => [
                    '@type' => 'Person',
                    'name' => $question->acceptedAnswer->user->name ?? 'Anonymous',
                ],
                'upvoteCount' => $question->acceptedAnswer->helpful_count,
            ];
        }

        // Add suggested answers
        $suggestedAnswers = $question->publishedAnswers()
            ->where('is_accepted', false)
            ->get()
            ->map(function ($answer) {
                return [
                    '@type' => 'Answer',
                    'text' => strip_tags($answer->content),
                    'dateCreated' => $answer->created_at->toIso8601String(),
                    'author' => [
                        '@type' => 'Person',
                        'name' => $answer->user->name ?? 'Anonymous',
                    ],
                    'upvoteCount' => $answer->helpful_count,
                ];
            });

        if ($suggestedAnswers->isNotEmpty()) {
            $schema['mainEntity']['suggestedAnswer'] = $suggestedAnswers->toArray();
        }

        return $schema;
    }

    /**
     * Generate sitemap data for discussions.
     *
     * @return \Illuminate\Support\Collection
     */
    public function getDiscussionSitemapData(): Collection
    {
        return Discussion::published()
            ->with('topic')
            ->select(['id', 'slug', 'updated_at', 'is_featured', 'view_count'])
            ->orderBy('updated_at', 'desc')
            ->get()
            ->map(function ($discussion) {
                return [
                    'loc' => $discussion->url,
                    'lastmod' => $discussion->updated_at->toIso8601String(),
                    'changefreq' => $discussion->is_featured ? 'daily' : 'weekly',
                    'priority' => $this->calculatePriority($discussion->view_count, $discussion->is_featured),
                ];
            });
    }

    /**
     * Generate sitemap data for knowledge base questions.
     *
     * @return \Illuminate\Support\Collection
     */
    public function getKnowledgeBaseSitemapData(): Collection
    {
        return KnowledgeBaseQuestion::published()
            ->with('category')
            ->select(['id', 'slug', 'updated_at', 'is_featured', 'view_count'])
            ->orderBy('updated_at', 'desc')
            ->get()
            ->map(function ($question) {
                return [
                    'loc' => $question->url,
                    'lastmod' => $question->updated_at->toIso8601String(),
                    'changefreq' => $question->is_featured ? 'daily' : 'weekly',
                    'priority' => $this->calculatePriority($question->view_count, $question->is_featured),
                ];
            });
    }

    /**
     * Generate sitemap data for discussion topics.
     *
     * @return \Illuminate\Support\Collection
     */
    public function getTopicSitemapData(): Collection
    {
        return DiscussionTopic::active()
            ->select(['id', 'slug', 'updated_at'])
            ->orderBy('name')
            ->get()
            ->map(function ($topic) {
                return [
                    'loc' => $topic->url,
                    'lastmod' => $topic->updated_at->toIso8601String(),
                    'changefreq' => 'weekly',
                    'priority' => '0.7',
                ];
            });
    }

    /**
     * Generate sitemap data for knowledge base categories.
     *
     * @return \Illuminate\Support\Collection
     */
    public function getCategorySitemapData(): Collection
    {
        return KnowledgeBaseCategory::active()
            ->select(['id', 'slug', 'updated_at'])
            ->orderBy('name')
            ->get()
            ->map(function ($category) {
                return [
                    'loc' => $category->url,
                    'lastmod' => $category->updated_at->toIso8601String(),
                    'changefreq' => 'weekly',
                    'priority' => '0.7',
                ];
            });
    }

    /**
     * Calculate priority based on views and featured status.
     *
     * @param int $viewCount
     * @param bool $isFeatured
     * @return string
     */
    protected function calculatePriority(int $viewCount, bool $isFeatured): string
    {
        if ($isFeatured) {
            return '1.0';
        }

        if ($viewCount > 1000) {
            return '0.9';
        }

        if ($viewCount > 500) {
            return '0.8';
        }

        if ($viewCount > 100) {
            return '0.7';
        }

        return '0.6';
    }

    /**
     * Extract keywords from text.
     *
     * @param string $text
     * @param int $maxKeywords
     * @return string
     */
    protected function extractKeywords(string $text, int $maxKeywords = 10): string
    {
        // Remove common words
        $stopWords = ['the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by', 'is', 'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could', 'should', 'may', 'might', 'must', 'this', 'that', 'these', 'those', 'i', 'you', 'he', 'she', 'it', 'we', 'they'];

        $words = str_word_count(strtolower(strip_tags($text)), 1);
        $words = array_diff($words, $stopWords);
        $wordCounts = array_count_values($words);
        arsort($wordCounts);

        return implode(', ', array_slice(array_keys($wordCounts), 0, $maxKeywords));
    }

    /**
     * Generate breadcrumb schema.
     *
     * @param array $items
     * @return array
     */
    public function generateBreadcrumbSchema(array $items): array
    {
        $itemListElements = [];
        $position = 1;

        foreach ($items as $item) {
            $itemListElements[] = [
                '@type' => 'ListItem',
                'position' => $position,
                'name' => $item['name'],
                'item' => $item['url'] ?? null,
            ];
            $position++;
        }

        return [
            '@context' => 'https://schema.org',
            '@type' => 'BreadcrumbList',
            'itemListElement' => $itemListElements,
        ];
    }

    /**
     * Get cached sitemap data.
     *
     * @param string $type
     * @return \Illuminate\Support\Collection
     */
    public function getCachedSitemapData(string $type): Collection
    {
        $cacheKey = "sitemap.{$type}";
        $cacheTtl = 60 * 60; // 1 hour

        return Cache::remember($cacheKey, $cacheTtl, function () use ($type) {
            return match ($type) {
                'discussions' => $this->getDiscussionSitemapData(),
                'knowledge-base' => $this->getKnowledgeBaseSitemapData(),
                'topics' => $this->getTopicSitemapData(),
                'categories' => $this->getCategorySitemapData(),
                default => collect(),
            };
        });
    }

    /**
     * Clear sitemap cache.
     *
     * @return void
     */
    public function clearSitemapCache(): void
    {
        Cache::forget('sitemap.discussions');
        Cache::forget('sitemap.knowledge-base');
        Cache::forget('sitemap.topics');
        Cache::forget('sitemap.categories');
    }

    /**
     * Generate meta tags HTML.
     *
     * @param array $metadata
     * @return string
     */
    public function generateMetaTags(array $metadata): string
    {
        $tags = [];

        // Basic meta tags
        if (!empty($metadata['title'])) {
            $tags[] = '<title>' . htmlspecialchars($metadata['title']) . '</title>';
            $tags[] = '<meta name="title" content="' . htmlspecialchars($metadata['title']) . '">';
        }

        if (!empty($metadata['description'])) {
            $tags[] = '<meta name="description" content="' . htmlspecialchars($metadata['description']) . '">';
        }

        if (!empty($metadata['keywords'])) {
            $tags[] = '<meta name="keywords" content="' . htmlspecialchars($metadata['keywords']) . '">';
        }

        if (!empty($metadata['canonical_url'])) {
            $tags[] = '<link rel="canonical" href="' . htmlspecialchars($metadata['canonical_url']) . '">';
        }

        // Open Graph tags
        if (!empty($metadata['og_type'])) {
            $tags[] = '<meta property="og:type" content="' . htmlspecialchars($metadata['og_type']) . '">';
        }

        if (!empty($metadata['og_title'])) {
            $tags[] = '<meta property="og:title" content="' . htmlspecialchars($metadata['og_title']) . '">';
        }

        if (!empty($metadata['og_description'])) {
            $tags[] = '<meta property="og:description" content="' . htmlspecialchars($metadata['og_description']) . '">';
        }

        if (!empty($metadata['og_url'])) {
            $tags[] = '<meta property="og:url" content="' . htmlspecialchars($metadata['og_url']) . '">';
        }

        // Twitter Card tags
        if (!empty($metadata['twitter_card'])) {
            $tags[] = '<meta name="twitter:card" content="' . htmlspecialchars($metadata['twitter_card']) . '">';
        }

        if (!empty($metadata['twitter_title'])) {
            $tags[] = '<meta name="twitter:title" content="' . htmlspecialchars($metadata['twitter_title']) . '">';
        }

        if (!empty($metadata['twitter_description'])) {
            $tags[] = '<meta name="twitter:description" content="' . htmlspecialchars($metadata['twitter_description']) . '">';
        }

        // Article specific tags
        if (!empty($metadata['article_published_time'])) {
            $tags[] = '<meta property="article:published_time" content="' . htmlspecialchars($metadata['article_published_time']) . '">';
        }

        if (!empty($metadata['article_modified_time'])) {
            $tags[] = '<meta property="article:modified_time" content="' . htmlspecialchars($metadata['article_modified_time']) . '">';
        }

        if (!empty($metadata['article_author'])) {
            $tags[] = '<meta property="article:author" content="' . htmlspecialchars($metadata['article_author']) . '">';
        }

        if (!empty($metadata['article_section'])) {
            $tags[] = '<meta property="article:section" content="' . htmlspecialchars($metadata['article_section']) . '">';
        }

        return implode("\n    ", $tags);
    }
}
