"""
Notification Model
In-app and push notification management
"""
import enum
from datetime import datetime
from typing import Optional
from sqlalchemy import (
    String, Boolean, Enum, Text, DateTime, ForeignKey, Index, JSON
)
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.models.base import BaseModel


class NotificationType(str, enum.Enum):
    """Notification category"""
    RIDE_REQUEST = "ride_request"
    RIDE_ACCEPTED = "ride_accepted"
    RIDE_STARTED = "ride_started"
    RIDE_COMPLETED = "ride_completed"
    RIDE_CANCELLED = "ride_cancelled"
    DRIVER_ARRIVED = "driver_arrived"
    NEW_BID = "new_bid"
    BID_ACCEPTED = "bid_accepted"
    BID_REJECTED = "bid_rejected"
    PAYMENT_RECEIVED = "payment_received"
    PAYMENT_FAILED = "payment_failed"
    WALLET_TOPUP = "wallet_topup"
    WITHDRAWAL_APPROVED = "withdrawal_approved"
    WITHDRAWAL_REJECTED = "withdrawal_rejected"
    PROMO_OFFER = "promo_offer"
    SYSTEM_ALERT = "system_alert"
    DRIVER_VERIFIED = "driver_verified"
    DOCUMENT_REJECTED = "document_rejected"
    ACCOUNT_UPDATE = "account_update"
    GENERAL = "general"


class NotificationChannel(str, enum.Enum):
    """Notification delivery channel"""
    PUSH = "push"
    EMAIL = "email"
    SMS = "sms"
    IN_APP = "in_app"


class Notification(BaseModel):
    """
    User notifications for in-app, push, SMS, and email.
    """
    __tablename__ = "notifications"
    
    # User reference
    user_id: Mapped[int] = mapped_column(
        ForeignKey("users.id", ondelete="CASCADE"),
        nullable=False,
        index=True
    )
    
    # Notification content
    title: Mapped[str] = mapped_column(String(255), nullable=False)
    body: Mapped[str] = mapped_column(Text, nullable=False)
    notification_type: Mapped[NotificationType] = mapped_column(
        Enum(NotificationType),
        default=NotificationType.GENERAL,
        nullable=False,
        index=True
    )
    
    # Channel
    channel: Mapped[NotificationChannel] = mapped_column(
        Enum(NotificationChannel),
        default=NotificationChannel.IN_APP,
        nullable=False
    )
    
    # Status
    is_read: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
    read_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    is_sent: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
    sent_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    
    # Action (deep link or action identifier)
    action_type: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
    action_data: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True)
    
    # Related entities
    ride_id: Mapped[Optional[int]] = mapped_column(
        ForeignKey("rides.id", ondelete="SET NULL"),
        nullable=True
    )
    
    # Image/icon
    image_url: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)
    
    # Priority
    priority: Mapped[str] = mapped_column(String(20), default="normal", nullable=False)
    
    # Expiry
    expires_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    
    # Relationships
    user: Mapped["User"] = relationship(
        "User",
        back_populates="notifications"
    )
    
    # Indexes
    __table_args__ = (
        Index('idx_notification_user_read', 'user_id', 'is_read'),
        Index('idx_notification_type_date', 'notification_type', 'created_at'),
    )


# Import for type hints
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from app.models.user import User
