use chrono::Utc;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

/// 审计日志记录。
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditLog {
    pub id: Uuid,
    pub tenant_id: Uuid,
    pub user_id: Option<Uuid>,
    pub action: String,
    pub resource_type: String,
    pub resource_id: Option<Uuid>,
    pub old_value: Option<serde_json::Value>,
    pub new_value: Option<serde_json::Value>,
    pub ip_address: Option<String>,
    pub user_agent: Option<String>,
    pub created_at: chrono::DateTime<Utc>,
}

impl AuditLog {
    /// 创建一条审计日志记录。
    pub fn new(
        tenant_id: Uuid,
        user_id: Option<Uuid>,
        action: impl Into<String>,
        resource_type: impl Into<String>,
    ) -> Self {
        Self {
            id: Uuid::now_v7(),
            tenant_id,
            user_id,
            action: action.into(),
            resource_type: resource_type.into(),
            resource_id: None,
            old_value: None,
            new_value: None,
            ip_address: None,
            user_agent: None,
            created_at: Utc::now(),
        }
    }

    /// 设置资源 ID。
    pub fn with_resource_id(mut self, id: Uuid) -> Self {
        self.resource_id = Some(id);
        self
    }

    /// 设置变更前后的值。
    pub fn with_changes(
        mut self,
        old: Option<serde_json::Value>,
        new: Option<serde_json::Value>,
    ) -> Self {
        self.old_value = old;
        self.new_value = new;
        self
    }

    /// 设置请求来源信息。
    pub fn with_request_info(mut self, ip: Option<String>, user_agent: Option<String>) -> Self {
        self.ip_address = ip;
        self.user_agent = user_agent;
        self
    }
}
