<?php

declare(strict_types=1);

namespace App\Http\Controllers\Marketing;

use App\Http\Controllers\Controller;
use App\Models\ArticleVote;
use App\Models\KnowledgeBaseArticle;
use App\Models\KnowledgeBaseCategory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class KnowledgeBaseController extends Controller
{
    public function index(): Response
    {
        $categories = KnowledgeBaseCategory::query()
            ->visible()
            ->root()
            ->withCount(['articles' => fn ($q) => $q->published()])
            ->with(['children' => fn ($q) => $q->visible()->withCount(['articles' => fn ($q2) => $q2->published()])])
            ->orderBy('sort_order')
            ->orderBy('name')
            ->get();

        $featuredArticles = KnowledgeBaseArticle::query()
            ->published()
            ->featured()
            ->with('category:id,name,slug')
            ->orderByDesc('published_at')
            ->limit(6)
            ->get();

        return Inertia::render('Marketing/KnowledgeBase/Index', [
            'categories' => $categories,
            'featuredArticles' => $featuredArticles,
        ]);
    }

    public function category(KnowledgeBaseCategory $category): Response
    {
        $category->loadCount(['articles' => fn ($q) => $q->published()]);

        $articles = KnowledgeBaseArticle::query()
            ->where('category_id', $category->id)
            ->published()
            ->orderByDesc('published_at')
            ->paginate(15);

        $subcategories = $category->children()
            ->visible()
            ->withCount(['articles' => fn ($q) => $q->published()])
            ->orderBy('sort_order')
            ->get();

        $breadcrumbs = $category->getAncestors()->map(fn (KnowledgeBaseCategory $ancestor) => [
            'name' => $ancestor->name,
            'slug' => $ancestor->slug,
        ])->push([
            'name' => $category->name,
            'slug' => $category->slug,
        ])->all();

        return Inertia::render('Marketing/KnowledgeBase/Category', [
            'category' => $category,
            'articles' => $articles,
            'subcategories' => $subcategories,
            'breadcrumbs' => $breadcrumbs,
        ]);
    }

    public function article(KnowledgeBaseCategory $category, KnowledgeBaseArticle $article): Response
    {
        if ($article->status !== 'published') {
            abort(404);
        }

        $article->increment('view_count');

        $article->load(['author:id,name', 'category:id,name,slug']);

        $breadcrumbs = $category->getAncestors()->map(fn (KnowledgeBaseCategory $ancestor) => [
            'name' => $ancestor->name,
            'slug' => $ancestor->slug,
        ])->push([
            'name' => $category->name,
            'slug' => $category->slug,
        ])->all();

        $relatedArticles = KnowledgeBaseArticle::query()
            ->where('category_id', $category->id)
            ->where('id', '!=', $article->id)
            ->published()
            ->orderByDesc('view_count')
            ->limit(5)
            ->get(['id', 'title', 'slug', 'excerpt', 'view_count', 'published_at']);

        $htmlContent = str($article->content)->markdown()->toString();

        return Inertia::render('Marketing/KnowledgeBase/Article', [
            'article' => $article,
            'htmlContent' => $htmlContent,
            'breadcrumbs' => $breadcrumbs,
            'relatedArticles' => $relatedArticles,
        ]);
    }

    public function search(Request $request): JsonResponse
    {
        $request->validate([
            'q' => ['required', 'string', 'min:2', 'max:100'],
        ]);

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

        $articles = KnowledgeBaseArticle::query()
            ->published()
            ->search($query)
            ->with('category:id,name,slug')
            ->limit(20)
            ->get(['id', 'title', 'slug', 'excerpt', 'category_id', 'view_count', 'published_at']);

        return response()->json([
            'articles' => $articles,
        ]);
    }

    public function vote(Request $request, KnowledgeBaseArticle $article): JsonResponse
    {
        $request->validate([
            'is_helpful' => ['required', 'boolean'],
        ]);

        $isHelpful = $request->boolean('is_helpful');
        $userId = $request->user()?->id;
        $ipAddress = $request->ip();

        $existingVote = ArticleVote::query()
            ->where('article_id', $article->id)
            ->when($userId, fn ($q) => $q->where('user_id', $userId))
            ->when(! $userId, fn ($q) => $q->whereNull('user_id')->where('ip_address', $ipAddress))
            ->first();

        if ($existingVote) {
            if ($existingVote->is_helpful === $isHelpful) {
                return response()->json([
                    'message' => 'You have already voted.',
                    'helpful_count' => $article->helpful_count,
                    'not_helpful_count' => $article->not_helpful_count,
                ]);
            }

            $existingVote->update(['is_helpful' => $isHelpful]);

            if ($isHelpful) {
                $article->increment('helpful_count');
                $article->decrement('not_helpful_count');
            } else {
                $article->decrement('helpful_count');
                $article->increment('not_helpful_count');
            }
        } else {
            ArticleVote::query()->create([
                'article_id' => $article->id,
                'user_id' => $userId,
                'is_helpful' => $isHelpful,
                'ip_address' => $ipAddress,
            ]);

            if ($isHelpful) {
                $article->increment('helpful_count');
            } else {
                $article->increment('not_helpful_count');
            }
        }

        $article->refresh();

        return response()->json([
            'message' => 'Thank you for your feedback!',
            'helpful_count' => $article->helpful_count,
            'not_helpful_count' => $article->not_helpful_count,
        ]);
    }
}
