"""
SQLAlchemy 基础类：
- Base           — 所有模型的声明式基类
- TimestampMixin — 自动维护 created_at / updated_at
- TenantMixin    — 多租户隔离字段 tenant_id
"""
from datetime import datetime
from typing import Any

from sqlalchemy import BigInteger, ForeignKey, event
from sqlalchemy.dialects.mysql import DATETIME as MYSQL_DATETIME, TINYINT
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, declared_attr


class Base(DeclarativeBase):
    """所有模型的基类，统一表选项：InnoDB + utf8mb4"""

    @declared_attr.directive
    def __tablename__(cls) -> str:
        # 默认表名 = 类名小写，子类可覆盖
        return cls.__name__.lower() + "s"

    __table_args__ = {
        "mysql_engine": "InnoDB",
        "mysql_charset": "utf8mb4",
        "mysql_collate": "utf8mb4_unicode_ci",
    }


class TimestampMixin:
    """自动维护创建 / 更新时间（毫秒精度 DATETIME(3)）"""

    created_at: Mapped[datetime] = mapped_column(
        MYSQL_DATETIME(fsp=3),
        nullable=False,
        default=datetime.utcnow,
        comment="创建时间 (UTC)",
    )
    updated_at: Mapped[datetime] = mapped_column(
        MYSQL_DATETIME(fsp=3),
        nullable=False,
        default=datetime.utcnow,
        onupdate=datetime.utcnow,
        comment="最后更新时间 (UTC)",
    )


class TenantMixin:
    """
    多租户隔离 Mixin。
    所有继承此类的模型在 SQLAlchemy 事件钩子中自动注入
    WHERE tenant_id = :current_tenant_id 过滤条件。
    """

    tenant_id: Mapped[int] = mapped_column(
        BigInteger,
        ForeignKey("tenants.id", ondelete="RESTRICT"),
        nullable=False,
        index=True,
        comment="租户 ID（多租户隔离必须字段）",
    )
