"""系统用户模型。"""

from __future__ import annotations

from datetime import datetime

from sqlalchemy import BigInteger, CheckConstraint, ForeignKey, Index, Integer, String, text
from sqlalchemy.dialects.mysql import DATETIME
from sqlalchemy.orm import Mapped, mapped_column

from dms.database.base import BusinessTableMixin
from dms.extensions import db


class User(BusinessTableMixin, db.Model):
    __tablename__ = "sys_user"
    __table_args__ = (
        CheckConstraint(
            "role_code IN ('USER', 'ADMIN')",
            name="user_role_code",
        ),
        CheckConstraint(
            "security_level IN "
            "('PUBLIC', 'INTERNAL', 'SECRET', 'CONFIDENTIAL', 'TOP_SECRET')",
            name="user_security_level",
        ),
        CheckConstraint(
            "status IN ('ENABLED', 'DISABLED')",
            name="user_status",
        ),
        Index(
            "ix_sys_user_organization_active_status",
            "organization_id",
            "is_deleted",
            "status",
        ),
        Index(
            "ix_sys_user_role_status_active",
            "role_code",
            "status",
            "is_deleted",
        ),
    )

    username: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)
    password_hash: Mapped[str] = mapped_column(String(255), nullable=False)
    real_name: Mapped[str] = mapped_column(String(64), nullable=False)
    organization_id: Mapped[int | None] = mapped_column(
        BigInteger,
        ForeignKey("sys_organization.id", ondelete="RESTRICT"),
        nullable=True,
    )
    organization_name: Mapped[str | None] = mapped_column(String(128), nullable=True)
    role_code: Mapped[str] = mapped_column(
        String(32),
        nullable=False,
        server_default=text("'USER'"),
    )
    security_level: Mapped[str] = mapped_column(
        String(32),
        nullable=False,
        server_default=text("'INTERNAL'"),
    )
    status: Mapped[str] = mapped_column(
        String(20),
        nullable=False,
        server_default=text("'ENABLED'"),
    )
    auth_version: Mapped[int] = mapped_column(
        Integer,
        nullable=False,
        server_default=text("0"),
    )
    last_login_at: Mapped[datetime | None] = mapped_column(
        DATETIME(fsp=3),
        nullable=True,
    )
    last_login_ip: Mapped[str | None] = mapped_column(String(64), nullable=True)
