from datetime import datetime

from sqlalchemy import BigInteger, Boolean, DateTime, ForeignKey, String, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column

from app.models.base import BaseModel


class Notification(BaseModel):
    """个人站内通知：系统针对单个用户自动生成。"""

    __tablename__ = "notifications"

    user_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
    )
    # system / order / instance / finance / ticket / promotion / membership
    category: Mapped[str] = mapped_column(String(24), default="system", nullable=False, index=True)
    # info / success / warning / error / urgent
    level: Mapped[str] = mapped_column(String(16), default="info", nullable=False, index=True)
    sender_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True, index=True)
    sender_name: Mapped[str | None] = mapped_column(String(100), nullable=True)
    sender_type: Mapped[str] = mapped_column(String(32), default="system", nullable=False)
    title: Mapped[str] = mapped_column(String(128), nullable=False)
    content: Mapped[str] = mapped_column(Text, nullable=False)
    link: Mapped[str | None] = mapped_column(String(256), nullable=True, comment="点击跳转的前端路径")
    action_label: Mapped[str | None] = mapped_column(String(40), nullable=True)
    action_url: Mapped[str | None] = mapped_column(String(256), nullable=True)
    is_read: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False, index=True)
    read_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    handled_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
    archived_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)


class NotificationPreference(BaseModel):
    """用户通知接收偏好。category 维度控制站内信/邮件/短信接收。"""

    __tablename__ = "notification_preferences"
    __table_args__ = (
        UniqueConstraint("user_id", "category", name="uq_notification_pref_user_category"),
    )

    user_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
    )
    category: Mapped[str] = mapped_column(String(24), nullable=False, index=True)
    in_app_enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
    email_enabled: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
    sms_enabled: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)


class NotificationEvent(BaseModel):
    """业务通知事件去重记录，用于避免定时任务重复发送同一事件。"""

    __tablename__ = "notification_events"
    __table_args__ = (
        UniqueConstraint("event_key", name="uq_notification_events_event_key"),
    )

    event_key: Mapped[str] = mapped_column(String(160), nullable=False)
    event_type: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
    user_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
    )
    resource_type: Mapped[str] = mapped_column(String(32), nullable=False, index=True)
    resource_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
