"""
Queue notification helpers for the notification system.

Provides helper functions for sending queue-related notifications
to keep the queue manager focused on queue logic.
"""

from typing import Dict, Any, Optional
from loguru import logger
from sqlalchemy.orm import Session

from .exceptions import RateLimitError
from .manager import NotificationManager
from .templates import EventType


def send_queue_notification(
    username: str,
    research_id: str,
    query: str,
    settings_snapshot: Dict[str, Any],
    position: Optional[int] = None,
) -> bool:
    """
    Send a research queued notification.

    Args:
        username: User who owns the research
        research_id: UUID of the research
        query: Research query string
        settings_snapshot: Settings snapshot for thread-safe access
        position: Queue position (optional)

    Returns:
        True if notification was sent successfully, False otherwise
    """
    try:
        notification_manager = NotificationManager(
            settings_snapshot=settings_snapshot, user_id=username
        )

        # Build notification context
        context: Dict[str, Any] = {
            "query": query,
            "research_id": research_id,
        }

        if position is not None:
            context["position"] = position
            context["wait_time"] = (
                "Unknown"  # Could estimate based on active researches
            )

        return notification_manager.send_notification(
            event_type=EventType.RESEARCH_QUEUED,
            context=context,
        )

    except RateLimitError:
        logger.warning(
            f"Rate limited sending queued notification for {research_id}"
        )
        return False
    except Exception:
        logger.warning(f"Failed to send queued notification for {research_id}")
        return False


def send_queue_failed_notification(
    username: str,
    research_id: str,
    query: str,
    error_message: Optional[str] = None,
    settings_snapshot: Optional[Dict[str, Any]] = None,
) -> bool:
    """
    Send a research failed notification from queue operations.

    Args:
        username: User who owns the research
        research_id: UUID of the research
        query: Research query string
        error_message: Optional error message
        settings_snapshot: Settings snapshot for thread-safe access

    Returns:
        True if notification was sent successfully, False otherwise
    """
    if not settings_snapshot:
        logger.debug("No settings snapshot provided for failed notification")
        return False

    try:
        notification_manager = NotificationManager(
            settings_snapshot=settings_snapshot, user_id=username
        )

        # Build notification context
        context = {
            "query": query,
            "research_id": research_id,
        }

        if error_message:
            context["error"] = error_message

        return notification_manager.send_notification(
            event_type=EventType.RESEARCH_FAILED,
            context=context,
        )

    except RateLimitError:
        logger.warning(
            f"Rate limited sending failed notification for {research_id}"
        )
        return False
    except Exception:
        logger.warning(f"Failed to send failed notification for {research_id}")
        return False


def send_queue_failed_notification_from_session(
    username: str,
    research_id: str,
    query: str,
    error_message: str,
    db_session: Session,
) -> None:
    """
    Send a research failed notification, fetching settings from db_session.

    This is a convenience wrapper for the queue processor that handles
    settings snapshot retrieval, logging, and error handling internally.
    All notification logic is contained within this function.

    Args:
        username: User who owns the research
        research_id: UUID of the research
        query: Research query string
        error_message: Error message to include in notification
        db_session: Database session to fetch settings from
    """
    try:
        from ..settings import SettingsManager

        # Get settings snapshot from database session
        settings_manager = SettingsManager(db_session)
        settings_snapshot = settings_manager.get_settings_snapshot()

        # Send notification (handles RateLimitError internally, returns False)
        success = send_queue_failed_notification(
            username=username,
            research_id=research_id,
            query=query,
            error_message=error_message,
            settings_snapshot=settings_snapshot,
        )

        if success:
            logger.info(f"Sent failure notification for research {research_id}")
        else:
            logger.warning(
                f"Failed to send failure notification for {research_id} (not sent)"
            )
    except Exception:
        logger.exception(
            f"Failed to send failure notification for {research_id}"
        )


def send_research_completed_notification_from_session(
    username: str,
    research_id: str,
    db_session: Session,
) -> None:
    """
    Send research completed notification with summary and URL.

    This is a convenience wrapper for the queue processor that handles
    all notification logic for completed research, including:
    - Research database lookup
    - Report content retrieval
    - URL building
    - Context building with summary
    - All logging and error handling

    Args:
        username: User who owns the research
        research_id: UUID of the research
        db_session: Database session to fetch research and settings from
    """
    try:
        logger.info(
            f"Starting completed notification process for research {research_id}, "
            f"user {username}"
        )

        # Import here to avoid circular dependencies
        from ..database.models import ResearchHistory
        from ..settings import SettingsManager
        from .manager import NotificationManager
        from .url_builder import build_notification_url

        # Get research details for notification
        research = (
            db_session.query(ResearchHistory).filter_by(id=research_id).first()
        )

        # Get settings snapshot for thread-safe notification sending
        settings_manager = SettingsManager(db_session)
        settings_snapshot = settings_manager.get_settings_snapshot()

        if research:
            logger.info(
                f"Found research record, creating NotificationManager "
                f"for user {username}"
            )

            # Create notification manager with settings snapshot
            notification_manager = NotificationManager(
                settings_snapshot=settings_snapshot, user_id=username
            )

            # Build full URL for notification
            full_url = build_notification_url(
                f"/research/{research_id}",
                settings_manager=settings_manager,
            )

            # Build notification context with required fields
            context = {
                "query": research.query or "Unknown query",
                "research_id": research_id,
                "summary": "No summary available",
                "url": full_url,
            }

            # Get report content for notification
            from ..storage import get_report_storage

            storage = get_report_storage(session=db_session)
            report_content = storage.get_report(research_id)

            if report_content:
                # Truncate summary if too long
                context["summary"] = (
                    report_content[:200] + "..."
                    if len(report_content) > 200
                    else report_content
                )

            logger.info(
                f"Sending RESEARCH_COMPLETED notification for research "
                f"{research_id} to user {username}"
            )
            logger.debug(f"Notification context: {context}")

            # Send notification using the manager
            result = notification_manager.send_notification(
                event_type=EventType.RESEARCH_COMPLETED,
                context=context,
            )

            if result:
                logger.info(
                    f"Successfully sent completion notification for research {research_id}"
                )
            else:
                logger.warning(
                    f"Completion notification not sent for {research_id} (disabled)"
                )

        else:
            logger.warning(
                f"Could not find research {research_id} in database, "
                f"sending notification with minimal details"
            )

            # Create notification manager with settings snapshot
            notification_manager = NotificationManager(
                settings_snapshot=settings_snapshot, user_id=username
            )

            # Build minimal context
            context = {
                "query": f"Research {research_id}",
                "research_id": research_id,
                "summary": "Research completed but details unavailable",
                "url": f"/research/{research_id}",
            }

            notification_manager.send_notification(
                event_type=EventType.RESEARCH_COMPLETED,
                context=context,
            )
            logger.info(
                f"Sent completion notification for research {research_id} (minimal details)"
            )

    except RateLimitError:
        logger.warning(
            f"Rate limited sending completion notification for {research_id}"
        )
    except Exception:
        logger.exception(
            f"Failed to send completion notification for {research_id}"
        )


def send_research_failed_notification_from_session(
    username: str,
    research_id: str,
    error_message: str,
    db_session: Session,
) -> None:
    """
    Send research failed notification (research-specific version).

    This is a convenience wrapper for the queue processor that handles
    all notification logic for failed research, including:
    - Research database lookup to get query
    - Context building with sanitized error message
    - All logging and error handling

    Args:
        username: User who owns the research
        research_id: UUID of the research
        error_message: Error message (will be sanitized for security)
        db_session: Database session to fetch research and settings from
    """
    try:
        logger.info(
            f"Starting failed notification process for research {research_id}, "
            f"user {username}"
        )

        # Import here to avoid circular dependencies
        from ..database.models import ResearchHistory
        from ..settings import SettingsManager
        from .manager import NotificationManager

        # Get research details for notification
        research = (
            db_session.query(ResearchHistory).filter_by(id=research_id).first()
        )

        # Get settings snapshot for thread-safe notification sending
        settings_manager = SettingsManager(db_session)
        settings_snapshot = settings_manager.get_settings_snapshot()

        # Sanitize error message for notification to avoid exposing
        # sensitive information (as noted by github-advanced-security)
        safe_error = "Research failed. Check logs for details."

        if research:
            logger.info(
                f"Found research record, creating NotificationManager "
                f"for user {username}"
            )

            # Create notification manager with settings snapshot
            notification_manager = NotificationManager(
                settings_snapshot=settings_snapshot, user_id=username
            )

            # Build notification context
            context = {
                "query": research.query or "Unknown query",
                "research_id": research_id,
                "error": safe_error,
            }

            logger.info(
                f"Sending RESEARCH_FAILED notification for research "
                f"{research_id} to user {username}"
            )
            logger.debug(f"Notification context: {context}")

            # Send notification using the manager
            result = notification_manager.send_notification(
                event_type=EventType.RESEARCH_FAILED,
                context=context,
            )

            if result:
                logger.info(
                    f"Successfully sent failure notification for research {research_id}"
                )
            else:
                logger.warning(
                    f"Failure notification not sent for {research_id} (disabled)"
                )

        else:
            logger.warning(
                f"Could not find research {research_id} in database, "
                f"sending notification with minimal details"
            )

            # Create notification manager with settings snapshot
            notification_manager = NotificationManager(
                settings_snapshot=settings_snapshot, user_id=username
            )

            # Build minimal context
            context = {
                "query": f"Research {research_id}",
                "research_id": research_id,
                "error": safe_error,
            }

            notification_manager.send_notification(
                event_type=EventType.RESEARCH_FAILED,
                context=context,
            )
            logger.info(
                f"Sent failure notification for research {research_id} (minimal details)"
            )

    except RateLimitError:
        logger.warning(
            f"Rate limited sending failure notification for {research_id}"
        )
    except Exception:
        logger.exception(
            f"Failed to send failure notification for {research_id}"
        )
