from django.http import HttpRequest, HttpResponse, JsonResponse, HttpResponseBadRequest
from django.shortcuts import render, get_object_or_404
from django.views.generic import DetailView, ListView
from django.views.decorators.http import require_POST
from django.utils.text import slugify

import re

from article_module.models import Article, ArticleCategory, ArticleComment


# -------------------------
# Articles List
# -------------------------
class ArticlesListView(ListView):
    template_name = 'article_module/article_page.html'
    model = Article
    paginate_by = 4

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        return context

    def get_queryset(self):
        query = super().get_queryset().filter(is_active=True)

        category_name = self.kwargs.get('category')
        if category_name:
            query = query.filter(
                selected_categories__url_title__iexact=category_name
            )

        return query


# -------------------------
# Article Detail
# -------------------------
class ArticleDetailView(DetailView):
    model = Article
    template_name = "article_module/article_detail.html"
    slug_field = "slug"
    slug_url_kwarg = "slug"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        article = self.object
        text = article.text or ""

        lines = text.split("\n")
        processed_lines = []
        toc = []

        for line in lines:
            if line.startswith("#"):
                match = re.match(r"^(#+)", line)

                if not match:
                    processed_lines.append(f"<p>{line}</p>")
                    continue

                level = len(match.group(1))
                title = line[level:].strip()
                anchor = slugify(title)

                toc.append({
                    "title": title,
                    "anchor": anchor,
                    "level": level
                })

                processed_lines.append(
                    f'<h{level} id="{anchor}">{title}</h{level}>'
                )

            else:
                processed_lines.append(
                    f"<p>{line}</p>" if line.strip() else "<br>"
                )

        context["article_content"] = "".join(processed_lines)
        context["toc"] = toc

        context["comments"] = (
            ArticleComment.objects
            .filter(article=article, parent=None)
            .order_by("-create_date")
            .prefetch_related("replies")
            .select_related("user")
        )

        context["comments_count"] = ArticleComment.objects.filter(
            article=article
        ).count()

        return context


# -------------------------
# Categories Component
# -------------------------
def articles_categories_component(request: HttpRequest):
    article_main_categories = (
        ArticleCategory.objects
        .prefetch_related('articlecategory_set')
        .filter(is_active=True, parent_id=None)
    )

    return render(
        request,
        'article_module/components/article_categories_component.html',
        {
            'main_categories': article_main_categories
        }
    )


# -------------------------
# Add Comment (Ajax)
# -------------------------
@require_POST
def add_article_comment(request):

    article_id = request.POST.get('article_id')
    text = request.POST.get('article_comment')
    parent_id = request.POST.get('parent_id')

    if not article_id or not text:
        return HttpResponseBadRequest("invalid data")

    article = get_object_or_404(Article, id=article_id)

    parent_comment = None
    if parent_id:
        parent_comment = ArticleComment.objects.filter(id=parent_id).first()

    comment = ArticleComment.objects.create(
        article=article,
        text=text.strip(),
        parent=parent_comment,
        user=request.user if request.user.is_authenticated else None
    )

    return JsonResponse({
        "status": "success",
        "comment": comment.text,
        "user": str(comment.user) if comment.user else "کاربر مهمان",
        "date": comment.create_date.strftime("%Y-%m-%d %H:%M")
    })


# -------------------------
# Related Articles
# -------------------------
def related_articles_component(request, article_id):

    article = get_object_or_404(Article, id=article_id)
    categories = article.selected_categories.all()

    if categories.exists():
        related_articles = (
            Article.objects
            .filter(
                is_active=True,
                selected_categories__in=categories
            )
            .exclude(id=article.id)
            .distinct()
            .order_by('-create_date')[:4]
        )
    else:
        related_articles = (
            Article.objects
            .filter(is_active=True)
            .exclude(id=article.id)
            .order_by('-create_date')[:4]
        )

    return render(
        request,
        'article_module/components/related_articles.html',
        {
            'related_articles': related_articles
        }
    )


# -------------------------
# Popular Articles
# -------------------------
def popular_articles_component(request):

    articles = (
        Article.objects
        .filter(is_active=True)
        .order_by('-create_date')[:6]
    )

    return render(
        request,
        'article_module/components/popular_articles.html',
        {
            'articles': articles
        }
    )
