<?php
declare(strict_types=1);

function mocker_admin_audit_actor(): array
{
    $kind = (string) ($_SESSION['mocker_admin_kind'] ?? 'master');
    $opId = isset($_SESSION['mocker_admin_id']) ? (int) $_SESSION['mocker_admin_id'] : 0;
    if ($kind !== 'staff') {
        $opId = 0;
    }
    $username = trim((string) ($_SESSION['mocker_admin_username'] ?? ''));
    if ($username === '') {
        $username = $kind === 'staff' ? '(personel)' : 'ana-yonetici';
    }
    $display = isset($_SESSION['mocker_admin_display']) ? trim((string) $_SESSION['mocker_admin_display']) : '';
    $display = $display !== '' ? $display : null;

    return [
        'kind' => $kind === 'staff' ? 'staff' : 'master',
        'operatorId' => $opId > 0 ? $opId : null,
        'username' => $username,
        'displayName' => $display,
    ];
}

function mocker_admin_audit_write(PDO $pdo, ?int $targetUserId, string $action, array $details): void
{
    try {
        $actor = mocker_admin_audit_actor();
        if (($actor['kind'] ?? '') !== 'staff') {
            // Ana super admin aksiyonlarını denetim tablosuna yazma.
            return;
        }
        $ip = trim((string) ($_SERVER['REMOTE_ADDR'] ?? ''));
        $ip = $ip !== '' ? $ip : null;
        $method = strtoupper((string) ($_SERVER['REQUEST_METHOD'] ?? 'GET'));
        $uri = (string) ($_SERVER['REQUEST_URI'] ?? '');
        $path = parse_url($uri, PHP_URL_PATH);
        $query = parse_url($uri, PHP_URL_QUERY);
        $path = is_string($path) ? $path : '';
        $query = is_string($query) ? $query : '';
        $ua = trim((string) ($_SERVER['HTTP_USER_AGENT'] ?? ''));
        $ua = $ua !== '' ? $ua : null;

        $mergedDetails = is_array($details) ? $details : [];
        $mergedDetails['_meta'] = [
            'path' => $path,
            'method' => $method,
            'query' => $query,
            'at' => time(),
        ];
        $j = json_encode($mergedDetails, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        if ($j === false) {
            $j = '{}';
        }
        $tid = $targetUserId !== null && $targetUserId > 0 ? $targetUserId : null;
        $ins = $pdo->prepare(
            'INSERT INTO admin_audit_log (
                created_at, actor_kind, actor_operator_id, actor_username, actor_display_name,
                action, target_user_id, details_json, ip, request_path, request_method, request_query, user_agent
             ) VALUES (
                :t, :k, :oid, :u, :d, :a, :tid, :dj, :ip, :rp, :rm, :rq, :ua
             )'
        );
        $ins->execute([
            ':t' => time(),
            ':k' => $actor['kind'],
            ':oid' => $actor['operatorId'],
            ':u' => $actor['username'],
            ':d' => $actor['displayName'],
            ':a' => $action,
            ':tid' => $tid,
            ':dj' => $j,
            ':ip' => $ip,
            ':rp' => $path,
            ':rm' => $method,
            ':rq' => $query,
            ':ua' => $ua,
        ]);
    } catch (Throwable $e) {
        error_log('mocker_admin_audit_write: ' . $e->getMessage());
    }
}

function mocker_admin_audit_log_send_json_response(): void
{
    if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
        http_response_code(405);
        echo json_encode(['ok' => false, 'error' => 'method'], JSON_UNESCAPED_UNICODE);
        exit;
    }

    $limit = isset($_GET['limit']) ? (int) $_GET['limit'] : 200;
    if ($limit < 1) {
        $limit = 1;
    }
    if ($limit > 500) {
        $limit = 500;
    }
    $offset = isset($_GET['offset']) ? (int) $_GET['offset'] : 0;
    if ($offset < 0) {
        $offset = 0;
    }

    $fromTs = isset($_GET['from']) ? (int) $_GET['from'] : 0;
    $toTs = isset($_GET['to']) ? (int) $_GET['to'] : 0;
    $hasRange = $fromTs > 0 && $toTs > 0 && $toTs >= $fromTs;
    if ($hasRange) {
        $maxSpan = 366 * 86400;
        if ($toTs - $fromTs > $maxSpan) {
            $fromTs = $toTs - $maxSpan;
        }
    }

    require_once __DIR__ . '/db.php';

    try {
        $pdo = mocker_db();
    } catch (Throwable $e) {
        http_response_code(503);
        echo json_encode(['ok' => false, 'error' => 'db'], JSON_UNESCAPED_UNICODE);
        exit;
    }

    if ($hasRange) {
        $stCnt = $pdo->prepare('SELECT COUNT(*) FROM admin_audit_log WHERE created_at >= :f AND created_at <= :t');
        $stCnt->execute([':f' => $fromTs, ':t' => $toTs]);
        $cnt = (int) $stCnt->fetchColumn();
        $st = $pdo->prepare(
            'SELECT id, created_at, actor_kind, actor_operator_id, actor_username, actor_display_name, action, target_user_id, details_json, ip,
                    request_path, request_method, request_query, user_agent
             FROM admin_audit_log WHERE created_at >= :f AND created_at <= :t ORDER BY id DESC LIMIT :lim OFFSET :off'
        );
        $st->bindValue(':f', $fromTs, PDO::PARAM_INT);
        $st->bindValue(':t', $toTs, PDO::PARAM_INT);
    } else {
        $cnt = (int) $pdo->query('SELECT COUNT(*) FROM admin_audit_log')->fetchColumn();
        $st = $pdo->prepare(
            'SELECT id, created_at, actor_kind, actor_operator_id, actor_username, actor_display_name, action, target_user_id, details_json, ip,
                    request_path, request_method, request_query, user_agent
             FROM admin_audit_log ORDER BY id DESC LIMIT :lim OFFSET :off'
        );
    }
    $st->bindValue(':lim', $limit, PDO::PARAM_INT);
    $st->bindValue(':off', $offset, PDO::PARAM_INT);
    $st->execute();
    $rows = $st->fetchAll(PDO::FETCH_ASSOC);

    $entries = [];
    foreach ($rows as $r) {
        $dj = (string) ($r['details_json'] ?? '{}');
        $details = json_decode($dj, true);
        if (!is_array($details)) {
            $details = [];
        }
        $entries[] = [
            'id' => (int) $r['id'],
            'createdAt' => (int) $r['created_at'],
            'actorKind' => (string) $r['actor_kind'],
            'actorOperatorId' => $r['actor_operator_id'] !== null ? (int) $r['actor_operator_id'] : null,
            'actorUsername' => (string) $r['actor_username'],
            'actorDisplayName' => $r['actor_display_name'] !== null && $r['actor_display_name'] !== '' ? (string) $r['actor_display_name'] : null,
            'action' => (string) $r['action'],
            'targetUserId' => $r['target_user_id'] !== null ? (int) $r['target_user_id'] : null,
            'details' => $details,
            'ip' => $r['ip'] !== null && $r['ip'] !== '' ? (string) $r['ip'] : null,
            'requestPath' => isset($r['request_path']) ? (string) $r['request_path'] : '',
            'requestMethod' => isset($r['request_method']) ? (string) $r['request_method'] : 'GET',
            'requestQuery' => isset($r['request_query']) ? (string) $r['request_query'] : '',
            'userAgent' => $r['user_agent'] !== null && $r['user_agent'] !== '' ? (string) $r['user_agent'] : null,
        ];
    }

    header('Content-Type: application/json; charset=utf-8');
    $payload = [
        'ok' => true,
        'total' => $cnt,
        'limit' => $limit,
        'offset' => $offset,
        'entries' => $entries,
    ];
    if ($hasRange) {
        $payload['filterFrom'] = $fromTs;
        $payload['filterTo'] = $toTs;
    }

    echo json_encode($payload, JSON_UNESCAPED_UNICODE);
}
