<?php

namespace Kylin\AuditLog\Models;

use Illuminate\Database\Eloquent\Model;

/**
 * 审计日志模型
 *
 * 记录系统操作审计日志，包括模型变更、操作用户、
 * IP 地址、User-Agent 等信息。
 *
 * 合规要求：
 *  - 依据《网络安全法》第二十一条，日志保留 >= 180 天
 *  - 依据《个人信息保护法》第二十八条，敏感字段脱敏
 *  - 依据等保 2.0 (GB/T 22239)，审计记录不可篡改
 */
class AuditLog extends Model
{
    protected $table = 'kylin_audit_logs';

    protected $fillable = [
        'event', 'model_type', 'model_id', 'old_values',
        'new_values', 'user_id', 'ip', 'user_agent', 'url', 'tag',
        'tenant_id',
    ];

    protected $guarded = ['id', 'created_at', 'updated_at'];

    protected $casts = [
        'old_values' => 'array',
        'new_values' => 'array',
    ];

    /**
     * 模型启动引导
     *
     * 依据等保 2.0 (GB/T 22239)，审计记录不可修改或删除。
     */
    protected static function booted(): void
    {
        if (config('kylin-audit-log.immutable', true)) {
            static::updating(function (self $log) {
                return false;
            });

            static::deleting(function (self $log) {
                return false;
            });
        }
    }

    /**
     * 敏感数据脱敏
     *
     * 依据《个人信息保护法》第二十八条，写入前对敏感字段脱敏。
     */
    public static function redactSensitiveFields(array $values): array
    {
        $sensitiveFields = config('kylin-audit-log.sensitive_fields', []);

        if (empty($sensitiveFields)) {
            return $values;
        }

        foreach ($values as $key => $value) {
            $keyLower = mb_strtolower((string) $key);
            foreach ($sensitiveFields as $sensitive) {
                if ($keyLower === mb_strtolower($sensitive)
                    || str_contains($keyLower, mb_strtolower($sensitive))
                ) {
                    $values[$key] = '[REDACTED]';
                    break;
                }
            }
        }

        return $values;
    }
}
