<?php

declare(strict_types=1);

namespace Kylin\AuditLog\Services;

use Kylin\AuditLog\Models\AuditLog;

class AuditLogService
{
    /**
     * 分页查询审计日志
     *
     * 支持按模型类型、事件类型、操作用户、时间范围过滤。
     */
    public function list(array $filters = [], int $perPage = 15)
    {
        $query = AuditLog::query();

        // 多租户隔离：依据《云计算服务安全评估办法》，不可跨租户访问
        $multiTenant = config('kylin-audit-log.multi_tenant', []);
        if (! empty($multiTenant['enabled']) && auth()->check()) {
            $tenantField = $multiTenant['tenant_field'] ?? 'tenant_id';
            $query->where($tenantField, auth()->user()->{$tenantField} ?? 0);
        }

        if (! empty($filters['model_type'])) {
            $query->where('model_type', $filters['model_type']);
        }
        if (! empty($filters['event'])) {
            $query->where('event', $filters['event']);
        }
        if (! empty($filters['user_id'])) {
            $query->where('user_id', $filters['user_id']);
        }
        if (! empty($filters['date_from'])) {
            $query->where('created_at', '>=', $filters['date_from']);
        }
        if (! empty($filters['date_to'])) {
            $query->where('created_at', '<=', $filters['date_to']);
        }

        return $query->orderByDesc('id')->paginate($perPage);
    }

    /**
     * 清理过期审计日志
     *
     * 依据《网络安全法》第二十一条，网络日志留存不少于 180 天。
     * 清理时强制最小保留 180 天，不可低于法律要求。
     * 使用 forceDelete() 绕过防篡改保护（清理操作需特权权限）。
     *
     * @param int $days 保留天数，必须 >= 180
     * @return int 删除的记录数
     */
    public function clean(int $days = 365): int
    {
        // 强制最小保留 180 天，不可低于《网络安全法》要求
        $minDays = 180;
        if ($days < $minDays) {
            $days = $minDays;
        }

        $cutoffDate = now()->subDays($days);

        // 使用 forceDelete() 绕过模型的防篡改保护
        return AuditLog::where('created_at', '<', $cutoffDate)->forceDelete();
    }
}
