from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session

from app.database import get_db
from app.dependencies import require_admin_token
from app.models import User
from app.schemas import (
    MemberNotificationIdRequest,
    MemberNotificationListResponse,
    MemberNotificationUnreadCountResponse,
    Message,
    NotificationRecipientListResponse,
    SendMemberNotificationRequest,
    SendMemberNotificationResponse,
)
from app.services.admin_service import (
    clear_all_member_notifications,
    count_unread_admin_member_notifications,
    delete_member_notification,
    list_member_notifications,
    list_notification_recipients,
    mark_all_member_notifications_read,
    mark_member_notification_read,
    send_member_notification,
    serialize_member_notification,
)
from app.services.email_otp import send_member_notification_email

router = APIRouter(tags=["admin-member-notifications"])


async def _email_notification_batch(
    targets: list[User],
    *,
    title: str,
    message: str,
    notification_type: str,
) -> None:
    for member in targets:
        try:
            await send_member_notification_email(
                member.email,
                title=title,
                message=message,
                notification_type=notification_type,
            )
        except Exception:
            pass


def _handle_send_message(
    body: SendMemberNotificationRequest,
    background_tasks: BackgroundTasks,
    db: Session,
    admin: User,
) -> SendMemberNotificationResponse:
    title = body.title.strip()
    message = body.message.strip()
    if not title:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Title is required")
    if not message:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Message is required")

    count, recipient_label, targets = send_member_notification(
        db,
        admin,
        user_id=body.user_id,
        notification_type=body.notification_type,
        title=title,
        message=message,
    )
    ntype = body.notification_type.strip().lower().replace(" ", "_")
    background_tasks.add_task(
        _email_notification_batch,
        targets,
        title=title,
        message=message,
        notification_type=ntype,
    )
    return SendMemberNotificationResponse(
        message=f"Notification sent to {recipient_label}",
        recipients_count=count,
        notification_type=ntype,
        title=title,
        recipient_label=recipient_label,
    )


@router.get(
    "/list-notification-recipients",
    response_model=NotificationRecipientListResponse,
    summary="List members for the Send Notifications recipient dropdown",
)
def list_recipients(
    db: Session = Depends(get_db),
    _: User = Depends(require_admin_token),
):
    members = list_notification_recipients(db)
    return NotificationRecipientListResponse(total=len(members), members=members)


@router.post(
    "/send-message",
    response_model=SendMemberNotificationResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Send a message/notification to one member or all members",
)
def send_message(
    body: SendMemberNotificationRequest,
    background_tasks: BackgroundTasks,
    db: Session = Depends(get_db),
    admin: User = Depends(require_admin_token),
):
    return _handle_send_message(body, background_tasks, db, admin)


@router.post(
    "/send-notification",
    response_model=SendMemberNotificationResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Alias for send-message (same behaviour)",
)
def send_notification(
    body: SendMemberNotificationRequest,
    background_tasks: BackgroundTasks,
    db: Session = Depends(get_db),
    admin: User = Depends(require_admin_token),
):
    return _handle_send_message(body, background_tasks, db, admin)


@router.get(
    "/list-member-notifications",
    response_model=MemberNotificationListResponse,
    summary="List member_notifications rows (inbox: visible only; management page: include_cleared=true)",
)
def list_member_notifications_route(
    include_cleared: bool = Query(
        True,
        description="Include rows hidden from bell (admin_cleared). Set false for inbox-only.",
    ),
    db: Session = Depends(get_db),
    _: User = Depends(require_admin_token),
):
    rows = list_member_notifications(db, include_cleared=include_cleared)
    serialized = [serialize_member_notification(n) for n in rows]
    return MemberNotificationListResponse(total=len(serialized), notifications=serialized)


@router.get(
    "/member-notifications-unread-count",
    response_model=MemberNotificationUnreadCountResponse,
    summary="Unread notification count for admin bell icon (is_read=false, admin_cleared=false)",
)
def admin_member_notifications_unread_count(
    db: Session = Depends(get_db),
    _: User = Depends(require_admin_token),
):
    return MemberNotificationUnreadCountResponse(
        unread_count=count_unread_admin_member_notifications(db)
    )


@router.post(
    "/mark-member-notification-read",
    response_model=Message,
    summary="Mark one notification as read (sets is_read=true)",
)
def mark_member_notification_read_route(
    body: MemberNotificationIdRequest,
    db: Session = Depends(get_db),
    _: User = Depends(require_admin_token),
):
    row = mark_member_notification_read(db, body.notification_id)
    if not row:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Notification not found")
    return Message(message="Notification marked as read")


@router.post(
    "/mark-all-member-notifications-read",
    response_model=Message,
    summary="Mark all visible notifications as read (admin)",
)
def mark_all_member_notifications_read_route(
    db: Session = Depends(get_db),
    _: User = Depends(require_admin_token),
):
    count = mark_all_member_notifications_read(db)
    return Message(message=f"Marked {count} notification(s) as read")


@router.post(
    "/clear-all-member-notifications",
    response_model=Message,
    summary="Hide all notifications from admin UI (admin_cleared=true; members keep them)",
)
def clear_all_member_notifications_route(
    db: Session = Depends(get_db),
    _: User = Depends(require_admin_token),
):
    count = clear_all_member_notifications(db)
    return Message(message=f"Cleared {count} notification(s) from admin view")


@router.post(
    "/delete-member-notification",
    response_model=Message,
    summary="Permanently delete one notification from admin notifications",
)
def delete_member_notification_route(
    body: MemberNotificationIdRequest,
    db: Session = Depends(get_db),
    _: User = Depends(require_admin_token),
):
    if not delete_member_notification(db, body.notification_id):
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Notification not found")
    return Message(message="Member notification deleted")
