"""
Notification Service — In-app notifications for stage transitions.
Stores notifications in DB and provides helpers to mark them read.
Optional email support via FastAPI-Mail (pip install fastapi-mail).
"""
from typing import List, Optional
from sqlalchemy.orm import Session

from ..models.models import User
from ..models.fyp2_models import Notification
from ..utils import utcnow


# ── DB notifications ─────────────────────────────────────────────────────────

def create_notification(
    db: Session,
    user_id: int,
    message: str,
    link: str = "",
    notif_type: str = "info",
) -> "Notification":
    """
    Create an in-app notification for a user.
    notif_type: 'info' | 'success' | 'warning' | 'hearing'
    """
    notif = Notification(
        user_id=user_id,
        message=message,
        link=link,
        notif_type=notif_type,
        is_read=False,
        created_at=utcnow(),
    )
    db.add(notif)
    db.commit()
    db.refresh(notif)
    return notif


def get_unread_notifications(db: Session, user_id: int) -> List["Notification"]:
    """Return all unread notifications for a user, newest first."""
    return (
        db.query(Notification)
        .filter(Notification.user_id == user_id, Notification.is_read == False)
        .order_by(Notification.created_at.desc())
        .all()
    )


def get_all_notifications(db: Session, user_id: int, limit: int = 20) -> List["Notification"]:
    """Return recent notifications for a user (read and unread)."""
    return (
        db.query(Notification)
        .filter(Notification.user_id == user_id)
        .order_by(Notification.created_at.desc())
        .limit(limit)
        .all()
    )


def mark_read(db: Session, notification_id: int, user_id: int) -> bool:
    """Mark a single notification as read. Returns True if found and updated."""
    notif = db.query(Notification).filter(
        Notification.id == notification_id,
        Notification.user_id == user_id,
    ).first()
    if not notif:
        return False
    notif.is_read = True
    db.commit()
    return True


def mark_all_read(db: Session, user_id: int) -> int:
    """Mark all notifications for a user as read. Returns count updated."""
    updated = (
        db.query(Notification)
        .filter(Notification.user_id == user_id, Notification.is_read == False)
        .update({"is_read": True})
    )
    db.commit()
    return updated


def unread_count(db: Session, user_id: int) -> int:
    """Return the count of unread notifications for navbar badge."""
    return (
        db.query(Notification)
        .filter(Notification.user_id == user_id, Notification.is_read == False)
        .count()
    )


# ── Event-driven helpers — call these from routers at each stage ──────────────

def notify_case_filed(db: Session, client_user_id: int, case_ref: str, case_id: int):
    """Notify client when their case is submitted."""
    create_notification(
        db, client_user_id,
        f"Your case {case_ref} has been submitted successfully.",
        link=f"/client/cases/{case_id}",
        notif_type="success",
    )


def notify_lawyer_accepted(db: Session, client_user_id: int, lawyer_name: str, case_ref: str, case_id: int):
    """Notify client when a lawyer accepts their case."""
    create_notification(
        db, client_user_id,
        f"Lawyer {lawyer_name} has accepted your case {case_ref}.",
        link=f"/client/cases/{case_id}",
        notif_type="success",
    )


def notify_court_filed(db: Session, client_user_id: int, filing_number: str, court_type: str, case_id: int):
    """Notify client when their case is formally filed in court."""
    create_notification(
        db, client_user_id,
        f"Your case has been filed in {court_type}. Filing No: {filing_number}",
        link=f"/client/cases/{case_id}",
        notif_type="info",
    )


def notify_hearing_scheduled(
    db: Session,
    client_user_id: int,
    lawyer_user_id: Optional[int],
    hearing_date: str,
    hearing_time: str,
    hearing_id: int,
    case_id: int,
):
    """Notify both client and lawyer when a hearing is scheduled."""
    msg = f"Hearing scheduled on {hearing_date} at {hearing_time}. Click to join."
    link = f"/hearing/{hearing_id}/join"

    create_notification(db, client_user_id, msg, link=link, notif_type="hearing")
    if lawyer_user_id:
        create_notification(db, lawyer_user_id, msg, link=link, notif_type="hearing")


def notify_case_resolved(db: Session, client_user_id: int, case_ref: str, case_id: int):
    """Notify client when their case is resolved."""
    create_notification(
        db, client_user_id,
        f"Your case {case_ref} has been resolved. View the order.",
        link=f"/client/cases/{case_id}",
        notif_type="success",
    )


# ── Optional email (fastapi-mail) — only active if EMAIL_HOST is set ──────────

def send_email_notification(to_email: str, subject: str, body: str):
    """
    Send email notification.
    Requires: pip install fastapi-mail
    Requires env vars: EMAIL_HOST, EMAIL_PORT, EMAIL_USERNAME, EMAIL_PASSWORD, EMAIL_FROM
    Silently skips if not configured.
    """
    import os
    email_host = os.getenv("EMAIL_HOST", "")
    if not email_host:
        print(f"[Notify] Email not configured — skipping email to {to_email}")
        return

    try:
        from fastapi_mail import FastMail, MessageSchema, ConnectionConfig
        conf = ConnectionConfig(
            MAIL_USERNAME=os.getenv("EMAIL_USERNAME", ""),
            MAIL_PASSWORD=os.getenv("EMAIL_PASSWORD", ""),
            MAIL_FROM=os.getenv("EMAIL_FROM", "noreply@legalease.ai"),
            MAIL_PORT=int(os.getenv("EMAIL_PORT", "587")),
            MAIL_SERVER=email_host,
            MAIL_STARTTLS=True,
            MAIL_SSL_TLS=False,
        )
        # Note: send_message is async — wrap in asyncio.create_task in async routes
        print(f"[Notify] Email configured — would send to {to_email}: {subject}")
    except ImportError:
        print("[Notify] fastapi-mail not installed — pip install fastapi-mail")
    except Exception as e:
        print(f"[Notify] Email send failed: {e}")
