"""
Notification API Endpoints - User notification management
"""
from fastapi import APIRouter, Depends, HTTPException, status, Query, Request
from sqlalchemy.orm import Session
from sqlalchemy import func
from typing import List, Optional
from datetime import datetime

from app.core.database import get_db
from app.services.notification_service import NotificationService
from app.schemas.notification import (
    NotificationCreate, NotificationResponse, NotificationListResponse,
    MarkReadRequest, DismissRequest, PendingApprovalResponse,
    NotificationSummaryResponse, WorkflowNotificationResponse
)
from app.models.notifications import Notification, NotificationUser
from app.models.user import User
from app.utils.logger import get_logger, log_exception, log_error_with_context

logger = get_logger(__name__)

router = APIRouter()


def get_current_user_id(request: Request, db: Session) -> Optional[str]:
    """Extract current user ID from request (simplified for development)"""
    # In production, this would validate JWT token
    # For now, check header or use a default
    user_id = request.headers.get("X-User-ID")
    if user_id:
        return user_id

    # Get first active user as fallback for development
    user = db.query(User).filter(User.active == True).first()
    return user.id if user else None


@router.get("/", response_model=NotificationListResponse)
async def get_notifications(
    request: Request,
    limit: int = Query(50, ge=1, le=100),
    offset: int = Query(0, ge=0),
    unread_only: bool = Query(False),
    category: Optional[str] = Query(None),
    db: Session = Depends(get_db)
):
    """Get notifications for the current user"""
    user_id = get_current_user_id(request, db)
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not authenticated"
        )

    service = NotificationService(db)
    service.sync_attention_notifications_for_user(user_id)

    notifications = service.get_user_notifications(
        user_id=user_id,
        limit=limit,
        offset=offset,
        unread_only=unread_only,
        category=category
    )

    unread_count = service.get_unread_count(user_id)

    # Get total count
    total_query = db.query(func.count(NotificationUser.id)).filter(
        NotificationUser.user_id == user_id,
        NotificationUser.dismissed == False
    )
    if category:
        total_query = total_query.join(Notification).filter(Notification.category == category)
    total = total_query.scalar() or 0

    return NotificationListResponse(
        notifications=[NotificationResponse(**n) for n in notifications],
        unread_count=unread_count,
        total=total
    )


@router.get("/unread", response_model=NotificationListResponse)
async def get_unread_notifications(
    request: Request,
    limit: int = Query(20, ge=1, le=50),
    db: Session = Depends(get_db)
):
    """Get unread notifications for the current user"""
    user_id = get_current_user_id(request, db)
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not authenticated"
        )

    service = NotificationService(db)

    notifications = service.get_user_notifications(
        user_id=user_id,
        limit=limit,
        unread_only=True
    )

    unread_count = service.get_unread_count(user_id)

    return NotificationListResponse(
        notifications=[NotificationResponse(**n) for n in notifications],
        unread_count=unread_count,
        total=unread_count
    )


@router.get("/summary", response_model=NotificationSummaryResponse)
async def get_notification_summary(
    request: Request,
    db: Session = Depends(get_db)
):
    """Get notification summary for the current user"""
    user_id = get_current_user_id(request, db)
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not authenticated"
        )

    service = NotificationService(db)
    service.sync_attention_notifications_for_user(user_id)

    unread_count = service.get_unread_count(user_id)
    pending_approvals = service.get_pending_approvals(user_id)

    # Count high priority unread
    high_priority_count = db.query(func.count(NotificationUser.id)).join(
        Notification
    ).filter(
        NotificationUser.user_id == user_id,
        NotificationUser.read == False,
        NotificationUser.dismissed == False,
        Notification.priority.in_(["high", "urgent"])
    ).scalar() or 0

    # Count by category
    category_counts = db.query(
        Notification.category,
        func.count(NotificationUser.id)
    ).join(NotificationUser).filter(
        NotificationUser.user_id == user_id,
        NotificationUser.read == False,
        NotificationUser.dismissed == False
    ).group_by(Notification.category).all()

    categories = {cat: count for cat, count in category_counts if cat}

    return NotificationSummaryResponse(
        unread_count=unread_count,
        pending_approvals_count=len(pending_approvals),
        high_priority_count=high_priority_count,
        categories=categories
    )


@router.get("/pending-approvals", response_model=List[PendingApprovalResponse])
async def get_pending_approvals(
    request: Request,
    db: Session = Depends(get_db)
):
    """Get pending approval items for the current user"""
    user_id = get_current_user_id(request, db)
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not authenticated"
        )

    service = NotificationService(db)
    service.sync_attention_notifications_for_user(user_id)
    approvals = service.get_pending_approvals(user_id)

    return [PendingApprovalResponse(**a) for a in approvals]


@router.get("/workflow", response_model=List[WorkflowNotificationResponse])
async def get_workflow_notifications(
    request: Request,
    unread_only: bool = Query(True),
    limit: int = Query(20, ge=1, le=50),
    db: Session = Depends(get_db)
):
    """Get workflow-specific notifications for the current user"""
    user_id = get_current_user_id(request, db)
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not authenticated"
        )

    service = NotificationService(db)
    notifications = service.get_workflow_notifications(
        user_id=user_id,
        unread_only=unread_only,
        limit=limit
    )

    return [WorkflowNotificationResponse(**n) for n in notifications]


@router.post("/mark-read")
async def mark_notification_read(
    request: Request,
    mark_read_request: MarkReadRequest,
    db: Session = Depends(get_db)
):
    """Mark notifications as read"""
    user_id = get_current_user_id(request, db)
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not authenticated"
        )

    service = NotificationService(db)
    count = service.mark_as_read(
        user_id=user_id,
        notification_ids=mark_read_request.notification_ids
    )

    return {
        "success": True,
        "marked_count": count,
        "message": f"Marked {count} notification(s) as read"
    }


@router.post("/mark-all-read")
async def mark_all_notifications_read(
    request: Request,
    db: Session = Depends(get_db)
):
    """Mark all notifications as read"""
    user_id = get_current_user_id(request, db)
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not authenticated"
        )

    service = NotificationService(db)
    count = service.mark_as_read(user_id=user_id)

    return {
        "success": True,
        "marked_count": count,
        "message": f"Marked {count} notification(s) as read"
    }


@router.post("/dismiss/{notification_id}")
async def dismiss_notification(
    notification_id: str,
    request: Request,
    db: Session = Depends(get_db)
):
    """Dismiss a notification (hide from list)"""
    user_id = get_current_user_id(request, db)
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not authenticated"
        )

    service = NotificationService(db)
    success = service.dismiss_notification(user_id, notification_id)

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

    return {"success": True, "message": "Notification dismissed"}


@router.post("/workflow/{notification_id}/read")
async def mark_workflow_notification_read(
    notification_id: str,
    request: Request,
    db: Session = Depends(get_db)
):
    """Mark a workflow notification as read"""
    user_id = get_current_user_id(request, db)
    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="User not authenticated"
        )

    service = NotificationService(db)
    success = service.mark_workflow_notification_read(notification_id, user_id)

    if not success:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Workflow notification not found"
        )

    return {"success": True, "message": "Notification marked as read"}


@router.post("/create", response_model=NotificationResponse, status_code=status.HTTP_201_CREATED)
async def create_notification(
    notification_data: NotificationCreate,
    request: Request,
    db: Session = Depends(get_db)
):
    """Create a new notification (admin/system use)"""
    user_id = get_current_user_id(request, db)

    service = NotificationService(db)
    notification = service.create_notification(
        title=notification_data.title,
        message=notification_data.message,
        user_ids=notification_data.user_ids,
        notification_type=notification_data.notification_type,
        category=notification_data.category,
        priority=notification_data.priority,
        action_url=notification_data.action_url,
        created_by=user_id,
        branch_id=notification_data.branch_id,
        expires_at=notification_data.expires_at,
        data=notification_data.data
    )

    return NotificationResponse(
        id=notification.id,
        title=notification.title,
        message=notification.message,
        notification_type=notification.notification_type,
        category=notification.category,
        priority=notification.priority,
        action_url=notification.action_url,
        data=notification.data,
        read=False,
        created_at=notification.created_at.isoformat() if notification.created_at else None,
        expires_at=notification.expires_at.isoformat() if notification.expires_at else None
    )
