from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File
from sqlalchemy.orm import Session
from typing import List
from datetime import datetime
import os
import uuid
from pathlib import Path
from PIL import Image
from config.database import get_db
from config.settings import settings
from models.post import Post, PostMention, PostLike, PostComment
from models.user import User
from models.notification import Notification, NotificationType
from utils.notification_service import NotificationService
from schemas.post import PostCreate, PostUpdate, PostResponse, PostCommentCreate
from utils.security import get_current_active_user
from utils.settings_service import SettingsService

router = APIRouter()

@router.post("/", response_model=PostResponse)
async def create_post(
    post_data: PostCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Create a new post."""
    post = Post(
        author_id=current_user.id,
        content=post_data.content,
        image_url=post_data.image_url
    )
    db.add(post)
    db.flush()  # Get the post ID before creating mentions
    
    # Create mentions
    for user_id in post_data.mentioned_user_ids:
        mentioned_user = db.query(User).filter(User.id == user_id).first()
        if mentioned_user:
            mention = PostMention(
                post_id=post.id,
                mentioned_user_id=user_id
            )
            db.add(mention)
            
            # Create notification for mentioned user
            NotificationService.create_mention_notification(
                db=db,
                mentioned_user_id=user_id,
                author=current_user,
                content_type="post",
                content_id=post.id
            )
    
    db.commit()
    db.refresh(post)
    return format_post_response(post, db)

@router.get("/", response_model=List[PostResponse])
async def get_posts(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),
    limit: int = 50,
    offset: int = 0
):
    """Get all posts."""
    posts = db.query(Post).order_by(Post.created_at.desc()).limit(limit).offset(offset).all()
    return [format_post_response(post, db) for post in posts]

@router.get("/{post_id}", response_model=PostResponse)
async def get_post(
    post_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Get a specific post."""
    post = db.query(Post).filter(Post.id == post_id).first()
    if not post:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Post not found"
        )
    return format_post_response(post, db)

@router.put("/{post_id}", response_model=PostResponse)
async def update_post(
    post_id: int,
    post_update: PostUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Update a post."""
    post = db.query(Post).filter(Post.id == post_id).first()
    if not post:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Post not found"
        )
    
    if post.author_id != current_user.id and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not authorized to update this post"
        )
    
    for field, value in post_update.dict(exclude_unset=True).items():
        setattr(post, field, value)
    
    post.updated_at = datetime.utcnow()
    db.commit()
    db.refresh(post)
    return format_post_response(post, db)

@router.delete("/{post_id}")
async def delete_post(
    post_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Delete a post."""
    post = db.query(Post).filter(Post.id == post_id).first()
    if not post:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Post not found"
        )
    
    if post.author_id != current_user.id and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not authorized to delete this post"
        )
    
    db.delete(post)
    db.commit()
    return {"message": "Post deleted successfully"}

@router.post("/upload-image")
async def upload_post_image(
    file: UploadFile = File(...),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Upload an image for a post."""
    # Validate file type
    if not SettingsService.is_file_type_allowed(db, file.content_type or "unknown"):
        allowed_types = SettingsService.get_setting(db, "allowed_image_types", 
            ["image/jpeg", "image/png", "image/gif", "image/webp"])
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Invalid file type. Allowed types: {', '.join(allowed_types)}"
        )
    
    # Check file size
    contents = await file.read()
    file_size = len(contents)
    max_size = SettingsService.get_max_upload_size(db, file.content_type or "image/jpeg")
    if file_size > max_size:
        max_size_mb = max_size // (1024 * 1024)
        raise HTTPException(
            status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
            detail=f"File too large. Maximum size: {max_size_mb}MB"
        )
    
    # Create posts directory
    posts_dir = Path(settings.UPLOAD_PATH) / "posts" / str(current_user.id)
    posts_dir.mkdir(parents=True, exist_ok=True)
    
    # Generate unique filename
    file_extension = file.filename.split(".")[-1]
    filename = f"{uuid.uuid4()}.{file_extension}"
    file_path = posts_dir / filename
    
    # Save file
    with open(file_path, "wb") as f:
        f.write(contents)
    
    # Resize image if it's REALLY too large (4K support)
    try:
        img = Image.open(file_path)
        if img.size[0] > 3840 or img.size[1] > 2160:  # 4K threshold
            img.thumbnail((3840, 2160), Image.Resampling.LANCZOS)
            img.save(file_path, quality=95, optimize=True)  # High quality
    except Exception as e:
        print(f"Error processing image: {e}")
    
    # Return the image URL
    image_url = f"/posts/{current_user.id}/{filename}"
    
    return {"image_url": image_url}

@router.post("/{post_id}/like")
async def toggle_post_like(
    post_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Toggle like on a post."""
    post = db.query(Post).filter(Post.id == post_id).first()
    if not post:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Post not found"
        )
    
    # Check if user already liked the post
    existing_like = db.query(PostLike).filter(
        PostLike.post_id == post_id,
        PostLike.user_id == current_user.id
    ).first()
    
    if existing_like:
        # Unlike
        db.delete(existing_like)
        post.likes_count = max(0, post.likes_count - 1)
        message = "Like removed"
        is_liked = False
    else:
        # Like
        like = PostLike(post_id=post_id, user_id=current_user.id)
        db.add(like)
        post.likes_count += 1
        message = "Post liked"
        is_liked = True
    
    db.commit()
    return {"message": message, "is_liked": is_liked, "likes_count": post.likes_count}

@router.post("/{post_id}/comment")
async def add_post_comment(
    post_id: int,
    comment_data: PostCommentCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Add a comment to a post."""
    post = db.query(Post).filter(Post.id == post_id).first()
    if not post:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Post not found"
        )
    
    comment = PostComment(
        post_id=post_id,
        author_id=current_user.id,
        content=comment_data.content
    )
    db.add(comment)
    db.commit()
    db.refresh(comment)
    
    return {
        "message": "Comment added successfully",
        "comment": {
            "id": comment.id,
            "content": comment.content,
            "author_id": comment.author_id,
            "author_name": current_user.full_name,
            "author_avatar": current_user.avatar_url,
            "created_at": comment.created_at
        }
    }

@router.delete("/{post_id}/comment/{comment_id}")
async def delete_post_comment(
    post_id: int,
    comment_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Delete a comment from a post."""
    comment = db.query(PostComment).filter(
        PostComment.id == comment_id,
        PostComment.post_id == post_id
    ).first()
    
    if not comment:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Comment not found"
        )
    
    if comment.author_id != current_user.id and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not authorized to delete this comment"
        )
    
    db.delete(comment)
    db.commit()
    return {"message": "Comment deleted successfully"}

def format_post_response(post: Post, db: Session) -> dict:
    """Format post response with author and mentions information."""
    mentioned_users = []
    for mention in post.mentions:
        user = mention.mentioned_user
        mentioned_users.append({
            "id": user.id,
            "username": user.username,
            "full_name": user.full_name,
            "avatar_url": user.avatar_url
        })
    
    # Get likes and comments
    likes = []
    for like in post.likes:
        user = db.query(User).filter(User.id == like.user_id).first()
        if user:
            likes.append({
                "id": like.id,
                "user_id": user.id,
                "username": user.username,
                "full_name": user.full_name,
                "avatar_url": user.avatar_url,
                "created_at": like.created_at
            })
    
    comments = []
    for comment in post.comments:
        user = db.query(User).filter(User.id == comment.author_id).first()
        if user:
            comments.append({
                "id": comment.id,
                "content": comment.content,
                "author_id": user.id,
                "author_name": user.full_name,
                "author_avatar": user.avatar_url,
                "created_at": comment.created_at
            })
    
    return {
        "id": post.id,
        "author_id": post.author_id,
        "content": post.content,
        "image_url": post.image_url,
        "likes_count": post.likes_count,
        "comments_count": post.comments_count,
        "created_at": post.created_at,
        "updated_at": post.updated_at,
        "author_name": post.author.full_name,
        "author_avatar": post.author.avatar_url,
        "mentioned_users": mentioned_users,
        "likes": likes,
        "comments": comments
    }
