# =============================================================================
# 用户角色关联模型 — user_roles 表
# =============================================================================
# 说明：用户与角色的多对多关联表，记录角色来源和分配信息
# =============================================================================

import uuid
from datetime import datetime
from typing import Optional

from sqlalchemy import String, DateTime, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import Mapped, mapped_column

from app.database import Base


class UserRole(Base):
    """用户角色关联模型 — 对应 user_roles 表。

    记录用户拥有的角色，支持以下来源：
    - auto: 系统自动分配（所有员工默认 user 角色）
    - tag: 企微标签映射
    - ehr: eHR 字段映射
    - manual: 管理后台手动分配
    """

    __tablename__ = "user_roles"
    __table_args__ = (
        # 同一用户同一角色只能有一条记录
        UniqueConstraint("employee_id", "role_id", name="uq_user_role"),
        # 按 employee_id 查询优化
        Index("idx_user_roles_employee_id", "employee_id"),
        # 按 role_id 查询优化
        Index("idx_user_roles_role_id", "role_id"),
    )

    # 主键：UUID
    id: Mapped[str] = mapped_column(
        String(36),
        primary_key=True,
        default=lambda: str(uuid.uuid4()),
    )

    # 企微 UserID
    employee_id: Mapped[str] = mapped_column(
        String(100),
        nullable=False,
        comment="企微 UserID",
    )

    # 角色 ID（外键）
    role_id: Mapped[str] = mapped_column(
        String(36),
        ForeignKey("roles.id", ondelete="CASCADE"),
        nullable=False,
        comment="角色 ID",
    )

    # 角色来源：auto/tag/ehr/manual
    source: Mapped[str] = mapped_column(
        String(50),
        nullable=False,
        comment="角色来源：auto/tag/ehr/manual",
    )

    # 分配者（手动分配时记录操作人）
    assigned_by: Mapped[Optional[str]] = mapped_column(
        String(100),
        nullable=True,
        comment="分配者（手动分配时记录操作人）",
    )

    # 分配时间
    assigned_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        nullable=False,
        default=datetime.now,
        comment="分配时间",
    )

    # 过期时间（可选，用于临时角色）
    expires_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True),
        nullable=True,
        comment="过期时间（可选，用于临时角色）",
    )

    def __repr__(self) -> str:
        return f"<UserRole(employee_id={self.employee_id}, role_id={self.role_id}, source={self.source})>"
