"""主案ACL允许权限模型。"""

from __future__ import annotations

from sqlalchemy import (
    BigInteger,
    Boolean,
    CheckConstraint,
    Computed,
    ForeignKey,
    Index,
    Integer,
    String,
    UniqueConstraint,
    text,
)
from sqlalchemy.orm import Mapped, mapped_column

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


class Permission(BusinessTableMixin, db.Model):
    __tablename__ = "doc_permission"
    __table_args__ = (
        CheckConstraint(
            "subject_type IN ('ORG', 'USER')",
            name="permission_subject_type",
        ),
        UniqueConstraint(
            "document_id",
            "subject_type",
            "subject_id",
            "active_marker",
            name="uq_doc_permission_active",
        ),
        Index(
            "ix_doc_permission_document_active",
            "document_id",
            "is_deleted",
        ),
        Index(
            "ix_doc_permission_subject_active",
            "subject_type",
            "subject_id",
            "is_deleted",
        ),
    )

    document_id: Mapped[int] = mapped_column(
        BigInteger,
        ForeignKey("doc_document.id", ondelete="RESTRICT"),
        nullable=False,
    )
    subject_type: Mapped[str] = mapped_column(String(20), nullable=False)
    subject_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
    subject_name: Mapped[str] = mapped_column(String(255), nullable=False)
    can_view: Mapped[bool] = mapped_column(
        Boolean,
        nullable=False,
        server_default=text("1"),
    )
    can_download: Mapped[bool] = mapped_column(
        Boolean,
        nullable=False,
        server_default=text("0"),
    )
    can_edit: Mapped[bool] = mapped_column(
        Boolean,
        nullable=False,
        server_default=text("0"),
    )
    can_manage_permission: Mapped[bool] = mapped_column(
        Boolean,
        nullable=False,
        server_default=text("0"),
    )
    can_delete: Mapped[bool] = mapped_column(
        Boolean,
        nullable=False,
        server_default=text("0"),
    )
    active_marker: Mapped[int | None] = mapped_column(
        Integer,
        Computed("IF(is_deleted = 0, 1, NULL)", persisted=False),
        nullable=True,
    )
