from django.shortcuts import get_object_or_404
from django.db.models import Q, Prefetch

from ninja import Router, Query
from typing import List, Optional

from users.models import User
from blog.models import Post, Category, Tag, Comment, Like
from api.authentication import jwt_auth
from api.schemas import (
    PostListSchema, PostDetailSchema, PostCreateSchema,
    CategorySchema, TagSchema, CommentSchema, CommentCreateSchema,
    MessageSchema, ErrorSchema
)

blog_router = Router()

# Post endpoints
@blog_router.get("/posts", response=List[PostListSchema])
def list_posts(
    request,
    page: int = Query(1, ge=1),
    limit: int = Query(10, ge=1, le=50),
    category: Optional[str] = None,
    tag: Optional[str] = None,
    search: Optional[str] = None,
    featured: Optional[bool] = None,
    author: Optional[str] = None
):
    """List published posts with filtering and pagination"""
    queryset = Post.objects.filter(status=Post.StatusChoices.PUBLISHED).select_related(
        'author', 'category'
    ).prefetch_related('tags')
    
    # Apply filters
    if category:
        queryset = queryset.filter(category__slug=category)
    
    if tag:
        queryset = queryset.filter(tags__slug=tag)
    
    if search:
        queryset = queryset.filter(
            Q(title__icontains=search) | 
            Q(content__icontains=search) |
            Q(excerpt__icontains=search)
        )
    
    if featured is not None:
        queryset = queryset.filter(is_featured=featured)
    
    if author:
        queryset = queryset.filter(author__username=author)
    
    # Pagination
    offset = (page - 1) * limit
    posts = queryset[offset:offset + limit]
    
    return posts

@blog_router.get("/posts/{slug}", response=PostDetailSchema)
def get_post(request, slug: str):
    """Get single post by slug"""
    post = get_object_or_404(
        Post.objects.select_related('author', 'category').prefetch_related('tags'),
        slug=slug,
        status=Post.StatusChoices.PUBLISHED
    )
    return post

@blog_router.post("/posts", response={201: PostDetailSchema, 400: ErrorSchema}, auth=jwt_auth)
def create_post(request, data: PostCreateSchema):
    """Create a new post (committee members only)"""
    user = request.auth
    
    if not (user.is_superuser or user.is_staff):
        return 400, {"error": "Only committee members can create posts"}
    
    try:
        post = Post.objects.create(
            title=data.title,
            content=data.content,
            excerpt=data.excerpt,
            author=user,
            category_id=data.category_id,
            status=data.status,
            is_featured=data.is_featured
        )
        
        if data.tag_ids:
            post.tags.set(data.tag_ids)
        
        return 201, post
        
    except Exception as e:
        return 400, {"error": "Failed to create post", "details": str(e)}

@blog_router.put("/posts/{slug}", response={200: PostDetailSchema, 400: ErrorSchema}, auth=jwt_auth)
def update_post(request, slug: str, data: PostCreateSchema):
    """Update a post (author or committee only)"""
    user = request.auth
    post = get_object_or_404(Post, slug=slug)
    
    if not (post.author == user or user.is_superuser or user.is_staff):
        return 400, {"error": "You can only edit your own posts"}
    
    try:
        for field, value in data.dict(exclude_unset=True).items():
            if field == 'tag_ids':
                if value:
                    post.tags.set(value)
            elif field == 'category_id':
                post.category_id = value
            else:
                setattr(post, field, value)
        
        post.save()
        return 200, post
        
    except Exception as e:
        return 400, {"error": "Failed to update post", "details": str(e)}

@blog_router.delete("/posts/{slug}", response={200: MessageSchema, 400: ErrorSchema}, auth=jwt_auth)
def delete_post(request, slug: str):
    """Soft delete a post owned by the requester or committee."""
    user = request.auth
    post = get_object_or_404(Post, slug=slug)
    
    if not (post.author == user or user.is_superuser or user.is_staff):
        return 400, {"error": "You can only delete your own posts"}
    
    post.delete()
    return 200, {"message": "Post deleted successfully"}

@blog_router.get("/deleted/posts", response=List[PostListSchema], auth=jwt_auth)
def list_deleted_posts(request):
    """List all soft-deleted posts (Admin/Committee only)"""
    if not (request.auth.is_staff or request.auth.is_superuser):
        return 403, {"error": "Permission denied"}
    return Post.deleted_objects.all().select_related('author', 'category').prefetch_related('tags')

@blog_router.post("deleted/posts/{post_id}/restore", response={200: MessageSchema, 400: ErrorSchema}, auth=jwt_auth)
def restore_post(request, post_id: int):
    """Restore a soft-deleted post (Admin/Committee only)"""
    if not (request.auth.is_staff or request.auth.is_superuser):
        return 403, {"error": "Permission denied"}
    try:
        post = Post.deleted_objects.get(id=post_id)
        post.restore()
        return 200, {"message": f"Post '{post.title}' restored successfully."}
    except Post.DoesNotExist:
        return 400, {"error": "Post not found or not soft-deleted."}



# Comment endpoints
@blog_router.get("/posts/{slug}/comments", response=List[CommentSchema])
def list_comments(request, slug: str):
    """List approved comments for a post"""
    post = get_object_or_404(Post, slug=slug, status=Post.StatusChoices.PUBLISHED)
    
    comments = Comment.objects.filter(
        post=post,
        is_approved=True,
        parent=None
    ).select_related('author').prefetch_related(
        Prefetch(
            'replies',
            queryset=Comment.objects.filter(is_approved=True).select_related('author')
        )
    )
    
    return comments

@blog_router.post("/posts/{slug}/comments", response={201: CommentSchema, 400: ErrorSchema}, auth=jwt_auth)
def create_comment(request, slug: str, data: CommentCreateSchema):
    """Create a comment on a post"""
    post = get_object_or_404(Post, slug=slug, status=Post.StatusChoices.PUBLISHED)
    user = request.auth
    
    try:
        comment = Comment.objects.create(
            post=post,
            author=user,
            content=data.content,
            parent_id=data.parent_id
        )
        
        return 201, comment
        
    except Exception as e:
        return 400, {"error": "Failed to create comment", "details": str(e)}

@blog_router.get("/deleted/comments", response=List[CommentSchema], auth=jwt_auth)
def list_deleted_comments(request):
    """List all soft-deleted comments (Admin/Committee only)"""
    if not (request.auth.is_staff or request.auth.is_superuser):
        return 403, {"error": "Permission denied"}
    return Comment.deleted_objects.all().select_related('author', 'post')

@blog_router.post("/deleted/comments/{comment_id}/restore", response={200: MessageSchema, 400: ErrorSchema}, auth=jwt_auth)
def restore_comment(request, comment_id: int):
    """Restore a soft-deleted comment (Admin/Committee only)"""
    if not (request.auth.is_staff or request.auth.is_superuser):
        return 403, {"error": "Permission denied"}
    try:
        comment = Comment.deleted_objects.get(id=comment_id)
        comment.restore()
        return 200, {"message": f"Comment by {comment.author.username} restored successfully."}
    except Comment.DoesNotExist:
        return 400, {"error": "Comment not found or not soft-deleted."}



# Like endpoints
@blog_router.post("/posts/{slug}/like", response={200: MessageSchema, 400: ErrorSchema}, auth=jwt_auth)
def toggle_like(request, slug: str):
    """Toggle like on a post"""
    post = get_object_or_404(Post, slug=slug, status=Post.StatusChoices.PUBLISHED)
    user = request.auth
    
    like, created = Like.objects.get_or_create(post=post, user=user)
    
    if not created:
        like.delete()
        return 200, {"message": "Post unliked"}
    
    return 200, {"message": "Post liked"}

@blog_router.get("/posts/{slug}/likes", response={200: MessageSchema})
def get_likes_count(request, slug: str):
    """Get likes count for a post"""
    post = get_object_or_404(Post, slug=slug, status=Post.StatusChoices.PUBLISHED)
    count = post.likes.count()
    return {"message": f"{count}"}



# Category endpoints
@blog_router.get("/categories", response=List[CategorySchema])
def list_categories(request):
    """List all categories"""
    return Category.objects.all()

@blog_router.get("/categories/{slug}", response=CategorySchema)
def get_category(request, slug: str):
    """Get single category by slug"""
    return get_object_or_404(Category, slug=slug)

@blog_router.get("/deleted/categories", response=List[CategorySchema], auth=jwt_auth)
def list_deleted_categories(request):
    """List all soft-deleted categories (Admin/Committee only)"""
    if not (request.auth.is_staff or request.auth.is_superuser):
        return 403, {"error": "Permission denied"}
    return Category.deleted_objects.all()

@blog_router.post("/deleted/categories/{category_id}/restore", response={200: MessageSchema, 400: ErrorSchema}, auth=jwt_auth)
def restore_category(request, category_id: int):
    """Restore a soft-deleted category (Admin/Committee only)"""
    if not (request.auth.is_staff or request.auth.is_superuser):
        return 403, {"error": "Permission denied"}
    try:
        category = Category.deleted_objects.get(id=category_id)
        category.restore()
        return 200, {"message": f"Category '{category.name}' restored successfully."}
    except Category.DoesNotExist:
        return 400, {"error": "Category not found or not soft-deleted."}



# Tag endpoints
@blog_router.get("/tags", response=List[TagSchema])
def list_tags(request):
    """List all tags"""
    return Tag.objects.all()

@blog_router.get("/tags/{slug}", response=TagSchema)
def get_tag(request, slug: str):
    """Get single tag by slug"""
    return get_object_or_404(Tag, slug=slug)

@blog_router.get("/deleted/tags", response=List[TagSchema], auth=jwt_auth)
def list_deleted_tags(request):
    """List all soft-deleted tags (Admin/Committee only)"""
    if not (request.auth.is_staff or request.auth.is_superuser):
        return 403, {"error": "Permission denied"}
    return Tag.all_objects.all()

@blog_router.post("/deleted/tags/{tag_id}/restore", response={200: MessageSchema, 400: ErrorSchema}, auth=jwt_auth)
def restore_tag(request, tag_id: int):
    """Restore a soft-deleted tag (Admin/Committee only)"""
    if not (request.auth.is_staff or request.auth.is_superuser):
        return 403, {"error": "Permission denied"}
    try:
        tag = Tag.deleted_objects.get(id=tag_id)
        tag.restore()
        return 200, {"message": f"Tag '{tag.name}' restored successfully."}
    except Tag.DoesNotExist:
        return 400, {"error": "Tag not found or not soft-deleted."}
