from sqlalchemy.orm import Session, joinedload
from fastapi import Request, HTTPException, status, BackgroundTasks
import re
from models.ticket_model import Ticket
from models.user_model import User
from models.comment_model import Comment
from schema.comment_schema import CommentAddSchema
from uuid import UUID
from utils.send_mention_email import send_mention_email
import os
from routers.websocket_router import manager

FRONTEND_URL = os.getenv("FRONTEND_URL", "http://localhost:3000")

def add_comment_in_ticket(payload:CommentAddSchema,request:Request,background_tasks: BackgroundTasks,db:Session):
    try:
        if not payload.content or not payload.ticket_id:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Content or ticket id is missing")
        check_if_ticket_exits=db.query(Ticket).filter(Ticket.id==payload.ticket_id).first()
        if not check_if_ticket_exits:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Ticket with this id doesnot exits!")
        
        add_comment=Comment(
            content=payload.content,
            ticket_id=payload.ticket_id,
            author_id=request.state.user.id,
            is_edited=False
        )
        db.add(add_comment)
        db.commit()
        db.refresh(add_comment)

        mentions = set(re.findall(r'@([a-zA-Z0-9_]+)', payload.content))
        if mentions and check_if_ticket_exits.project:
            org_users = db.query(User).filter(User.org_id == check_if_ticket_exits.project.org_id).all()
            ticket_link = f"/dashboard/project/{check_if_ticket_exits.project.id}?ticket={check_if_ticket_exits.ticket_number}"
            
            # Import notification service here to avoid circular imports if needed
            from services.notification_service import create_notification

            for mention in mentions:
                for user in org_users:
                    if user.name and user.name.replace(" ", "").lower() == mention.lower():
                        if user.id != request.state.user.id:
                            # 1. Send Email
                            background_tasks.add_task(
                                send_mention_email,
                                email=user.email,
                                mentioned_by_name=request.state.user.name,
                                ticket_name=check_if_ticket_exits.title,
                                ticket_number=check_if_ticket_exits.ticket_number,
                                comment_text=payload.content,
                                ticket_link=f"{FRONTEND_URL}{ticket_link}"
                            )
                            # 2. Create In-App Notification
                            create_notification(
                                db=db,
                                user_id=user.id,
                                message=f"{request.state.user.name} mentioned you in a comment on {check_if_ticket_exits.ticket_number}",
                                link=ticket_link
                            )
                        break

        background_tasks.add_task(
            manager.broadcast_to_project,
            str(check_if_ticket_exits.project_id),
            {"event": "comment_added", "data": {"ticket_id": str(payload.ticket_id), "comment_id": str(add_comment.id)}}
        )

        return {
            "message":"Comment added successfully!!"
        }
    except HTTPException as e:
        raise e
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Error:{str(e)}")
    
def get_comment_for_ticket_id(ticket_id:UUID, request:Request,db:Session):
    try:
        if not ticket_id:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Ticket id is required to get the comments")
        all_comments=db.query(Comment).filter(Comment.ticket_id==ticket_id).options(
            joinedload(Comment.ticket),joinedload(Comment.author).load_only(User.name, User.email)
        ).all()
        return {
            "comments":all_comments
        }
    except HTTPException as e:
        raise e
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Error:{str(e)}")
    

def update_comment(
    payload: CommentAddSchema,
    comment_id: UUID,
    request: Request,
    background_tasks: BackgroundTasks,
    db: Session
):
    try:
        if not comment_id:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Comment id is required to update comment"
            )

        if not payload.content:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Content is required to update comment"
            )

        comment = (
            db.query(Comment)
            .filter(Comment.id == comment_id,Comment.author_id==request.state.user.id)
            .first()
        )

        if not comment:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Comment not found"
            )

        comment.content = payload.content
        comment.is_edited = True

        db.commit()
        db.refresh(comment)
        
        # Check if project exists to get project_id, although comments belong to tickets which belong to projects
        ticket = db.query(Ticket).filter(Ticket.id == comment.ticket_id).first()
        if ticket:
            background_tasks.add_task(
                manager.broadcast_to_project,
                str(ticket.project_id),
                {"event": "comment_updated", "data": {"ticket_id": str(ticket.id), "comment_id": str(comment.id)}}
            )

        return {
            "message": "Comment updated successfully!"
        }

    except HTTPException as e:
        raise e

    except Exception as e:
        db.rollback()

        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Error: {str(e)}"
        )
    


def delete_comment(
    comment_id: UUID,
    request: Request,
    background_tasks: BackgroundTasks,
    db: Session
):
    try:
        if not comment_id:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Comment id is required to update comment"
            )

        comment = (
            db.query(Comment)
            .filter(Comment.id == comment_id,Comment.author_id==request.state.user.id)
            .first()
        )

        if not comment:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Comment not found"
            )
        ticket_id = comment.ticket_id
        db.delete(comment)
        db.commit()

        ticket = db.query(Ticket).filter(Ticket.id == ticket_id).first()
        if ticket:
            background_tasks.add_task(
                manager.broadcast_to_project,
                str(ticket.project_id),
                {"event": "comment_deleted", "data": {"ticket_id": str(ticket.id), "comment_id": str(comment_id)}}
            )

        return {
            "message": "Comment deleted successfully!"
        }

    except HTTPException as e:
        raise e

    except Exception as e:
        db.rollback()

        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Error: {str(e)}"
        )