# =============================================================================
# 企微IT智能服务台 — 审计日志模型
# =============================================================================
# 说明: 对应数据库 audit_logs 表,记录所有高危/RBAC 操作 + 登录/MFA 事件
# 给 auditor 角色 + admin 提供只读审计能力
#
# 何时写入:
#   - 高危操作 (role_change / config_change / data_export / account_disable / account_create_reset)
#   - RBAC 操作 (assign_role / revoke_role / create_mapping_rule / delete_mapping_rule)
#   - 登录事件 (qrcode_login / sso_login / password_login)
#   - MFA 事件 (bind / verify / reset)
#   - 业务敏感操作 (resolve_conversation / transfer_conversation)
# =============================================================================

import uuid
from datetime import datetime
from typing import Optional

from sqlalchemy import JSON, DateTime, Index, String, Text
from sqlalchemy.orm import Mapped, mapped_column

from app.database import Base


class AuditLog(Base):
    """审计日志模型 — 对应 audit_logs 表。

    Attributes:
        id: 日志唯一标识(UUID)
        employee_id: 操作人(企微 UserID,系统操作填 "system")
        action: 操作类型(如 "role_change", "login", "mfa_verify")
        resource: 目标资源类型("agent" / "conversation" / "system_config" 等)
        resource_id: 目标资源 ID
        details: 详细上下文(JSON,前后值/IP/UA 等)
        result: "success" / "failure" / "partial"
        ip_address: 操作来源 IP(可选)
        user_agent: 操作来源 UA(可选)
        created_at: 时间
    """

    __tablename__ = "audit_logs"

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

    # 操作人(企微 UserID, 系统操作填 "system")
    employee_id: Mapped[str] = mapped_column(
        String(100),
        nullable=False,
        comment="操作人(employee_id / 'system')",
    )

    # 操作类型
    # 例: "role_change" / "config_change" / "login" / "mfa_verify" /
    #     "qrcode_login" / "sso_login" / "password_login" /
    #     "resolve_conversation" / "transfer_conversation" / "data_export"
    action: Mapped[str] = mapped_column(
        String(50),
        nullable=False,
        comment="操作类型",
    )

    # 目标资源类型
    # 例: "agent" / "conversation" / "system_config" / "role" / "user_role"
    resource: Mapped[str] = mapped_column(
        String(50),
        nullable=False,
        comment="目标资源类型",
    )

    # 目标资源 ID(字符串,跨表通用)
    resource_id: Mapped[Optional[str]] = mapped_column(
        String(100),
        nullable=True,
        comment="目标资源 ID",
    )

    # 详细上下文(JSON)
    # 例: {"role": "agent", "reason": "新员工转岗", "ip": "10.80.0.5"}
    details: Mapped[Optional[dict]] = mapped_column(
        JSON,
        nullable=True,
        comment="详细上下文(JSON)",
    )

    # 结果
    # "success" / "failure" / "partial"
    result: Mapped[str] = mapped_column(
        String(20),
        nullable=False,
        default="success",
        comment="执行结果",
    )

    # 来源 IP
    ip_address: Mapped[Optional[str]] = mapped_column(
        String(64),
        nullable=True,
        comment="来源 IP",
    )

    # 来源 User-Agent
    user_agent: Mapped[Optional[str]] = mapped_column(
        Text,
        nullable=True,
        comment="来源 User-Agent",
    )

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

    # 索引:按 employee_id / action / time 查询
    __table_args__ = (
        Index("idx_audit_employee_id", "employee_id"),
        Index("idx_audit_action", "action"),
        Index("idx_audit_resource", "resource", "resource_id"),
        Index("idx_audit_created_at", "created_at"),
    )

    def __repr__(self) -> str:
        return f"<AuditLog(action={self.action}, employee={self.employee_id}, result={self.result})>"
