<?php

declare(strict_types=1);

namespace App\Models;

class AuditLog extends BaseModel
{
    protected string $table = 'audit_logs';

    public function log(?int $userId, string $action, string $entityType, ?int $entityId, ?array $oldValues, ?array $newValues, string $ipAddress): void
    {
        $this->create([
            'user_id' => $userId,
            'action' => $action,
            'entity_type' => $entityType,
            'entity_id' => $entityId,
            'old_values' => $oldValues ? json_encode($oldValues) : null,
            'new_values' => $newValues ? json_encode($newValues) : null,
            'ip_address' => $ipAddress,
        ]);
    }

    public function getLogs(array $filters = [], int $page = 1, int $perPage = 30): array
    {
        $where = [];
        $params = [];

        if (!empty($filters['user_id'])) {
            $where[] = 'a.user_id = :user_id';
            $params['user_id'] = (int) $filters['user_id'];
        }
        if (!empty($filters['action'])) {
            $where[] = 'a.action = :action';
            $params['action'] = $filters['action'];
        }
        if (!empty($filters['entity_type'])) {
            $where[] = 'a.entity_type = :entity_type';
            $params['entity_type'] = $filters['entity_type'];
        }

        $perPage = max(1, $perPage);
        $whereClause = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';
        $offset = ($page - 1) * $perPage;

        $total = (int) $this->queryOne(
            "SELECT COUNT(*) as cnt FROM {$this->table} a {$whereClause}",
            $params
        )['cnt'];

        $items = $this->query(
            "SELECT a.*, u.name as user_name
             FROM {$this->table} a
             LEFT JOIN users u ON a.user_id = u.id
             {$whereClause}
             ORDER BY a.created_at DESC
             LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

        return ['items' => $items, 'total' => $total, 'page' => $page, 'per_page' => $perPage, 'total_pages' => (int) ceil($total / max(1, $perPage))];
    }
}
