<?php
require_once 'auth.php';
ensureAdminAuth();
require_once '../config/database.php';
require_once '../includes/app_helpers.php';

$database = new Database();
$db = $database->getConnection();

ensureOperationalTables($db);
ensureCsrTeamTables($db);

function al_h($value) {
    if (function_exists('h')) return h($value);
    return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
}

function al_fetch_map(PDO $db, $sql, $idKey = 'id', $labelKey = 'name') {
    try {
        $rows = $db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
        $map = [];
        foreach ($rows as $row) {
            if (isset($row[$idKey])) $map[(string)$row[$idKey]] = trim((string)($row[$labelKey] ?? ''));
        }
        return $map;
    } catch (Throwable $e) {
        return [];
    }
}

$statusMap = [
    '1' => 'New Request',
    '2' => 'Assigned',
    '3' => 'In Progress',
    '4' => 'Completed',
    '5' => 'Cancelled',
];
try {
    $statusRows = $db->query("SELECT id, status_name FROM job_statuses ORDER BY id")->fetchAll(PDO::FETCH_ASSOC);
    foreach ($statusRows as $row) {
        $statusMap[(string)$row['id']] = $row['status_name'];
    }
} catch (Throwable $e) {}

$valueMaps = [
    'brand_id' => al_fetch_map($db, "SELECT id, name FROM brands"),
    'appliance_id' => al_fetch_map($db, "SELECT id, name FROM appliances"),
    'technician_id' => al_fetch_map($db, "SELECT id, TRIM(CONCAT(COALESCE(first_name,''), ' ', COALESCE(last_name,''))) AS name FROM technicians"),
    'assigned_csr_id' => al_fetch_map($db, "SELECT id, TRIM(CONCAT(COALESCE(first_name,''), ' ', COALESCE(last_name,''))) AS name FROM csr_users"),
    'created_by_csr_id' => al_fetch_map($db, "SELECT id, TRIM(CONCAT(COALESCE(first_name,''), ' ', COALESCE(last_name,''))) AS name FROM csr_users"),
];

$logs = [];
try {
    $sql = "
        SELECT
            rl.*,
            sr.request_number,
            COALESCE(NULLIF(TRIM(CONCAT(cu.first_name, ' ', cu.last_name)), ''), rl.actor_name) AS resolved_actor_name,
            COALESCE(cu.email, rl.actor_email) AS resolved_actor_email,
            COALESCE(cu.role, rl.user_role) AS resolved_role,
            COALESCE(
                NULLIF(GROUP_CONCAT(DISTINCT member_team.team_name ORDER BY member_team.team_name SEPARATOR ', '), ''),
                NULLIF(GROUP_CONCAT(DISTINCT leader_team.team_name ORDER BY leader_team.team_name SEPARATOR ', '), ''),
                CASE
                    WHEN rl.user_role = 'admin' THEN 'Admin'
                    WHEN COALESCE(cu.role, rl.user_role) = 'csr_manager' THEN 'CSR Manager / All Teams'
                    ELSE 'Unassigned'
                END
            ) AS team_belong
        FROM request_logs rl
        LEFT JOIN service_requests sr ON sr.id = rl.request_id
        LEFT JOIN csr_users cu ON cu.id = rl.user_id AND rl.user_role IN ('csr','team_leader','csr_manager')
        LEFT JOIN csr_team_members tm ON tm.csr_id = cu.id
        LEFT JOIN csr_teams member_team ON member_team.id = tm.team_id AND member_team.is_active = 1
        LEFT JOIN csr_teams leader_team ON leader_team.manager_id = cu.id AND leader_team.is_active = 1
        GROUP BY rl.id
        ORDER BY rl.created_at DESC
        LIMIT 300
    ";
    $logs = $db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
} catch (Throwable $e) {
    try {
        $logs = $db->query("SELECT rl.*, sr.request_number, 'Unassigned' AS team_belong, rl.actor_name AS resolved_actor_name, rl.actor_email AS resolved_actor_email, rl.user_role AS resolved_role FROM request_logs rl LEFT JOIN service_requests sr ON sr.id = rl.request_id ORDER BY rl.created_at DESC LIMIT 300")->fetchAll(PDO::FETCH_ASSOC);
    } catch (Throwable $e2) {
        $logs = [];
    }
}

function al_action_label($action) {
    $labels = [
        'status_change' => 'Status changed',
        'manual_ticket_created' => 'Manual ticket created',
        'request_claimed' => 'Request claimed',
        'note_added' => 'Note added',
        'customer_notified' => 'Customer notified',
        'ticket_updated' => 'Ticket updated',
        'request_updated' => 'Request updated',
        'technician_assigned' => 'Technician assigned',
        'bulk_technician_assigned' => 'Technician assigned',
    ];
    $action = (string)$action;
    return $labels[$action] ?? ucwords(str_replace('_', ' ', $action));
}

function al_role_label($role, $savedLabel = '') {
    $savedLabel = trim((string)$savedLabel);
    if ($savedLabel !== '') return $savedLabel;
    $role = (string)$role;
    if ($role === 'admin') return 'Admin';
    if ($role === 'csr_manager') return 'CSR Manager';
    if ($role === 'team_leader') return 'Team Leader';
    if ($role === 'csr') return 'CSR Agent';
    return ucwords(str_replace('_', ' ', $role));
}

function al_decode($value) {
    $value = trim((string)$value);
    if ($value === '') return null;
    if (substr($value, 0, 1) !== '{' && substr($value, 0, 1) !== '[') return null;
    $decoded = json_decode($value, true);
    return is_array($decoded) ? $decoded : null;
}

function al_field_label($key) {
    $labels = [
        'job_status_id' => 'Status',
        'status_id' => 'Status',
        'status' => 'Status',
        'request_number' => 'Ticket number',
        'manual_ticket_number' => 'Manual ticket number',
        'customer_name' => 'Customer name',
        'customer_phone' => 'Customer phone',
        'phone_number' => 'Phone number',
        'secondary_phone' => 'Second phone',
        'customer_email' => 'Customer email',
        'email' => 'Email',
        'brand_id' => 'Brand',
        'appliance_id' => 'Appliance',
        'assigned_csr_id' => 'Assigned CSR',
        'created_by_csr_id' => 'Created by CSR',
        'technician_id' => 'Technician',
        'urgency_level' => 'Urgency',
        'preferred_date' => 'Preferred date',
        'preferred_time' => 'Preferred time',
        'service_address' => 'Service address',
        'address' => 'Address',
        'city' => 'City',
        'state' => 'State',
        'zip_code' => 'ZIP code',
        'notes' => 'Notes',
        'special_request' => 'Special request',
        'model_number' => 'Model number',
        'product_model_version' => 'Model/version',
        'serial_number' => 'Serial number',
        'purchase_date' => 'Purchase date',
        'warranty_status' => 'Warranty status',
        'warranty_type' => 'Warranty type',
        'follow_up_reminder' => 'Follow-up reminder',
        'follow_up_due_at' => 'Follow-up due',
        'ticket_source' => 'Ticket source',
    ];
    $key = (string)$key;
    return $labels[$key] ?? ucwords(str_replace('_', ' ', $key));
}

function al_value_label($field, $value, array $statusMap, array $valueMaps) {
    if ($value === null || $value === '') return '—';
    if (is_array($value)) return json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

    $field = strtolower((string)$field);
    $raw = trim((string)$value);

    if (in_array($field, ['job_status_id', 'status_id', 'status'], true)) {
        return $statusMap[$raw] ?? ('Status #' . $raw);
    }
    if ($field === 'urgency_level') {
        $urgency = ['1' => 'Normal', '2' => 'Urgent', '3' => 'Emergency'];
        return $urgency[$raw] ?? $raw;
    }
    if (isset($valueMaps[$field]) && isset($valueMaps[$field][$raw]) && $valueMaps[$field][$raw] !== '') {
        return $valueMaps[$field][$raw];
    }
    if ($raw === '0') return 'No';
    if ($raw === '1' && !preg_match('/(^|_)id$/', $field)) return 'Yes';
    return $raw;
}

function al_same($a, $b) {
    if (is_array($a)) $a = json_encode($a);
    if (is_array($b)) $b = json_encode($b);
    return trim((string)$a) === trim((string)$b);
}

function al_build_easy_log(array $log, array $statusMap, array $valueMaps) {
    $action = (string)($log['action'] ?? '');
    $oldRaw = $log['old_value'] ?? '';
    $newRaw = $log['new_value'] ?? '';
    $notes = trim((string)($log['notes'] ?? ''));
    $ticket = $log['request_number'] ?: ('#' . ($log['request_id'] ?? ''));
    $actor = trim((string)($log['resolved_actor_name'] ?? $log['actor_name'] ?? 'Someone')) ?: 'Someone';
    $fields = [];
    $headline = '';
    $plain = '';
    $category = 'Update';

    if ($action === 'status_change') {
        $old = al_value_label('job_status_id', $oldRaw, $statusMap, $valueMaps);
        $new = al_value_label('job_status_id', $newRaw, $statusMap, $valueMaps);
        $fields[] = ['field' => 'Status', 'old' => $old, 'new' => $new, 'changed' => true];
        $headline = 'Status changed from ' . $old . ' to ' . $new;
        $plain = $actor . ' moved ticket ' . $ticket . ' from ' . $old . ' to ' . $new . '.';
        $category = 'Status';
    } else {
        $oldJson = al_decode($oldRaw);
        $newJson = al_decode($newRaw);

        if (is_array($oldJson) || is_array($newJson)) {
            $oldArr = is_array($oldJson) ? $oldJson : [];
            $newArr = is_array($newJson) ? $newJson : [];
            $keys = array_values(array_unique(array_merge(array_keys($oldArr), array_keys($newArr))));
            $skip = ['csrf_token', 'submit', 'password', 'confirm_password'];
            foreach ($keys as $key) {
                if (in_array($key, $skip, true) || stripos($key, 'password') !== false || stripos($key, 'token') !== false) continue;
                $oldVal = $oldArr[$key] ?? '';
                $newVal = $newArr[$key] ?? '';
                if (al_same($oldVal, $newVal)) continue;
                $fields[] = [
                    'field' => al_field_label($key),
                    'old' => al_value_label($key, $oldVal, $statusMap, $valueMaps),
                    'new' => al_value_label($key, $newVal, $statusMap, $valueMaps),
                    'changed' => true,
                ];
            }

            if (count($fields) === 1) {
                $headline = $fields[0]['field'] . ' changed';
                $plain = $actor . ' changed ' . strtolower($fields[0]['field']) . ' from ' . $fields[0]['old'] . ' to ' . $fields[0]['new'] . '.';
            } elseif (count($fields) > 1) {
                $names = array_slice(array_column($fields, 'field'), 0, 3);
                $headline = count($fields) . ' ticket fields changed';
                $plain = $actor . ' updated ' . implode(', ', $names) . (count($fields) > 3 ? ' and more' : '') . ' on ticket ' . $ticket . '.';
            } else {
                $headline = al_action_label($action);
                $plain = $actor . ' made an update, but no changed fields were saved in detail.';
                $fields[] = ['field' => 'Saved data', 'old' => $oldRaw ?: '—', 'new' => $newRaw ?: '—', 'changed' => false];
            }
            $category = 'Edit';
        } else {
            if ($action === 'manual_ticket_created') {
                $headline = 'Manual ticket created';
                $plain = $actor . ' created manual ticket ' . ($newRaw ?: $ticket) . '.';
                $fields[] = ['field' => 'Ticket number', 'old' => '—', 'new' => $newRaw ?: $ticket, 'changed' => true];
                $category = 'Created';
            } elseif ($action === 'request_claimed') {
                $headline = 'Ticket claimed';
                $plain = $actor . ' claimed ticket ' . $ticket . '.';
                $fields[] = ['field' => 'Claimed by', 'old' => '—', 'new' => $newRaw ?: $actor, 'changed' => true];
                $category = 'Claimed';
            } elseif ($action === 'note_added') {
                $headline = 'Note added';
                $plain = $actor . ' added a note to ticket ' . $ticket . '.';
                $fields[] = ['field' => 'Note type', 'old' => '—', 'new' => $newRaw ?: 'Note added', 'changed' => true];
                $category = 'Note';
            } elseif ($action === 'customer_notified') {
                $headline = 'Customer notified';
                $plain = $actor . ' notified the customer for ticket ' . $ticket . ($newRaw ? ' via ' . $newRaw : '') . '.';
                $fields[] = ['field' => 'Notification method', 'old' => '—', 'new' => $newRaw ?: 'Sent', 'changed' => true];
                $category = 'Notify';
            } else {
                $headline = al_action_label($action);
                $plain = $actor . ' performed this action on ticket ' . $ticket . '.';
                $fields[] = ['field' => al_action_label($action), 'old' => $oldRaw ?: '—', 'new' => $newRaw ?: '—', 'changed' => trim((string)$oldRaw) !== trim((string)$newRaw)];
            }
        }
    }

    if ($notes !== '') {
        $fields[] = ['field' => 'Notes', 'old' => '—', 'new' => $notes, 'changed' => false];
    }

    $before = '—';
    $after = '—';
    foreach ($fields as $row) {
        if (!empty($row['changed'])) {
            $before = $row['old'] ?? '—';
            $after = $row['new'] ?? '—';
            break;
        }
    }

    return [
        'headline' => $headline,
        'plain' => $plain,
        'category' => $category,
        'before' => $before,
        'after' => $after,
        'fields' => $fields,
    ];
}

$todayCount = 0;
$statusCount = 0;
$createdCount = 0;
$uniqueTickets = [];
foreach ($logs as $row) {
    if (!empty($row['created_at']) && date('Y-m-d', strtotime($row['created_at'])) === date('Y-m-d')) $todayCount++;
    if (($row['action'] ?? '') === 'status_change') $statusCount++;
    if (($row['action'] ?? '') === 'manual_ticket_created') $createdCount++;
    $uniqueTickets[(string)($row['request_number'] ?: $row['request_id'])] = true;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Activity Logs - Admin</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;800;900&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="../assets/theme.css">
    <link rel="stylesheet" href="../assets/portal-dark.css">
    <link rel="stylesheet" href="../assets/ushs-global-theme.css">
    <link rel="stylesheet" href="../assets/admin-sidebar.css">
    <style>
        :root{
            --al-bg-a:#080240;--al-bg-b:#073449;--al-card:#13275a;--al-card-2:#0e2148;
            --al-cyan:#20d7f5;--al-blue:#48a7ff;--al-text:#f4f8ff;--al-muted:#aebbd4;
            --al-line:rgba(117,178,255,.22);--al-good:#4ade80;--al-warn:#facc15;--al-bad:#fb7185;
        }
        body{background:linear-gradient(135deg,var(--al-bg-a),var(--al-bg-b)) fixed!important;color:var(--al-text)!important;font-family:Montserrat,Arial,sans-serif!important;}
        .main-content{margin-left:250px;padding:24px;min-height:100vh;}
        .al-page{max-width:1500px;margin:0 auto;}
        .al-card{background:linear-gradient(135deg,rgba(19,39,90,.98),rgba(14,33,72,.98));border:1px solid rgba(32,215,245,.24);border-radius:22px;box-shadow:0 16px 42px rgba(0,0,0,.28);}
        .al-header{padding:22px;display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:18px;}
        .al-title{display:flex;gap:14px;align-items:center;}
        .al-title-icon{width:48px;height:48px;border-radius:16px;background:rgba(32,215,245,.14);display:grid;place-items:center;color:var(--al-cyan);font-size:1.25rem;box-shadow:inset 0 0 0 1px rgba(32,215,245,.25);}
        .al-title h1{font-size:1.55rem;font-weight:900;margin:0;letter-spacing:-.02em;}
        .al-title p{margin:3px 0 0;color:var(--al-muted);font-weight:600;font-size:.88rem;}
        .al-actions{display:flex;gap:10px;flex-wrap:wrap;}
        .al-btn{border:1px solid rgba(32,215,245,.38);background:rgba(32,215,245,.12);color:#e8fbff!important;border-radius:999px;padding:10px 15px;font-weight:900;text-decoration:none;display:inline-flex;align-items:center;gap:8px;transition:.16s ease;}
        .al-btn:hover{background:rgba(32,215,245,.23);transform:translateY(-1px);}
        .al-btn-dark{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.16);}
        .al-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;margin-bottom:18px;}
        .al-stat{padding:18px;border-radius:18px;background:rgba(8,20,48,.42);border:1px solid var(--al-line);}
        .al-stat span{display:block;color:var(--al-muted);font-size:.76rem;font-weight:900;text-transform:uppercase;letter-spacing:.06em;}
        .al-stat strong{display:block;margin-top:5px;font-size:1.75rem;font-weight:900;color:#fff;}
        .al-help{padding:17px 19px;margin-bottom:18px;border-radius:20px;background:linear-gradient(135deg,rgba(32,215,245,.13),rgba(72,167,255,.08));border:1px solid rgba(32,215,245,.22);display:flex;gap:12px;align-items:flex-start;}
        .al-help i{color:var(--al-cyan);margin-top:2px;}.al-help strong{color:#fff}.al-help div{color:#cfe0ff;font-weight:600;font-size:.9rem;line-height:1.45;}
        .al-toolbar{padding:16px;display:grid;grid-template-columns:1fr 220px 180px;gap:12px;margin-bottom:18px;}
        .al-input,.al-select{width:100%;border:1px solid var(--al-line);background:rgba(5,15,38,.5);border-radius:14px;color:#fff;padding:12px 14px;font-weight:700;outline:0;}
        .al-input::placeholder{color:#8fa1c4}.al-select option{background:#0e2148;color:#fff;}
        .al-list{display:grid;gap:12px;}
        .al-log{padding:16px;border-radius:20px;background:rgba(9,24,58,.54);border:1px solid var(--al-line);display:grid;grid-template-columns:180px 1fr 220px 130px;gap:14px;align-items:center;transition:.15s ease;}
        .al-log:hover{background:rgba(16,41,92,.72);border-color:rgba(32,215,245,.32);}
        .al-time{font-weight:900;color:#edf6ff;}.al-time small{display:block;color:var(--al-muted);font-size:.73rem;margin-top:4px;}
        .al-mainline{min-width:0;}.al-badges{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:7px;}
        .al-badge{border-radius:999px;padding:5px 9px;font-size:.68rem;font-weight:900;text-transform:uppercase;letter-spacing:.04em;background:rgba(32,215,245,.15);color:#aaf4ff;border:1px solid rgba(32,215,245,.24);}
        .al-ticket{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.14);color:#fff;}
        .al-headline{font-weight:900;color:#fff;font-size:1rem;margin-bottom:3px;}
        .al-plain{color:#cfe0ff;font-size:.86rem;font-weight:600;line-height:1.4;}
        .al-person strong{display:block;color:#fff;font-weight:900;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.al-person small{display:block;color:var(--al-muted);font-weight:700;font-size:.73rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:3px;}
        .al-view{justify-self:end;border:0;background:linear-gradient(135deg,#20d7f5,#0ea5e9);color:#052136;border-radius:999px;padding:10px 14px;font-weight:900;display:inline-flex;align-items:center;gap:7px;box-shadow:0 10px 22px rgba(14,165,233,.24);}
        .al-empty{padding:28px;text-align:center;color:var(--al-muted);font-weight:800;}
        .al-modal-backdrop{position:fixed;inset:0;background:rgba(2,6,23,.74);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;z-index:5000;padding:20px;}
        .al-modal-backdrop.show{display:flex;}
        .al-modal{width:min(940px,96vw);max-height:88vh;overflow:auto;background:linear-gradient(135deg,#17295e,#0d1f44);border:1px solid rgba(32,215,245,.34);border-radius:24px;box-shadow:0 26px 90px rgba(0,0,0,.5);}
        .al-modal-head{padding:20px 22px;border-bottom:1px solid var(--al-line);display:flex;justify-content:space-between;gap:12px;align-items:flex-start;}
        .al-modal-title{font-size:1.15rem;font-weight:900;margin:0;color:#fff;}.al-modal-sub{font-size:.8rem;color:var(--al-muted);font-weight:700;margin-top:5px;line-height:1.4;}
        .al-close{width:42px;height:42px;border-radius:14px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.08);color:#fff;font-size:1.4rem;line-height:1;}
        .al-modal-body{padding:20px 22px;}.al-explain{padding:15px;border-radius:18px;background:rgba(32,215,245,.10);border:1px solid rgba(32,215,245,.20);color:#dffbff;font-weight:750;line-height:1.45;margin-bottom:16px;}
        .al-changes{display:grid;gap:12px;}.al-change{border:1px solid rgba(117,178,255,.20);border-radius:18px;background:rgba(8,20,48,.34);overflow:hidden;}.al-change.changed{border-color:rgba(250,204,21,.42);box-shadow:inset 4px 0 0 rgba(250,204,21,.75);}
        .al-change-field{padding:12px 14px;font-weight:900;color:#fff;border-bottom:1px solid rgba(117,178,255,.14);background:rgba(255,255,255,.04);}.al-change-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;padding:12px;}
        .al-label{font-size:.68rem;text-transform:uppercase;letter-spacing:.06em;color:var(--al-muted);font-weight:900;margin-bottom:6px;}.al-value{min-height:44px;border-radius:14px;padding:11px 12px;white-space:pre-wrap;word-break:break-word;font-weight:800;line-height:1.35;}
        .al-old{background:rgba(251,113,133,.12);border:1px solid rgba(251,113,133,.25);color:#ffe1e6;}.al-new{background:rgba(74,222,128,.12);border:1px solid rgba(74,222,128,.25);color:#ddffe8;}
        @media(max-width:1100px){.main-content{margin-left:0;padding:14px}.al-stats{grid-template-columns:repeat(2,1fr)}.al-toolbar{grid-template-columns:1fr}.al-log{grid-template-columns:1fr}.al-view{justify-self:start}.al-person strong,.al-person small{white-space:normal}.al-time small{display:inline;margin-left:8px}}
        @media(max-width:640px){.al-stats{grid-template-columns:1fr}.al-change-grid{grid-template-columns:1fr}.al-title h1{font-size:1.25rem}.al-header{padding:16px}}
    </style>
</head>
<body>
<?php require_once __DIR__ . '/admin_sidebar.php'; render_admin_sidebar(); ?>

<main class="main-content">
    <div class="al-page">
        <section class="al-card al-header">
            <div class="al-title">
                <div class="al-title-icon"><i class="fas fa-list-check"></i></div>
                <div>
                    <h1>Activity Logs</h1>
                    <p>Simple view for who changed what, when, and from what value to what value.</p>
                </div>
            </div>
            <div class="al-actions">
                <button type="button" class="al-btn al-btn-dark" onclick="history.back()"><i class="fas fa-arrow-left"></i> Back</button>
                <a class="al-btn" href="activity_logs.php"><i class="fas fa-rotate-right"></i> Refresh</a>
            </div>
        </section>

        <section class="al-stats">
            <div class="al-stat"><span>Total logs shown</span><strong><?= al_h(count($logs)) ?></strong></div>
            <div class="al-stat"><span>Logs today</span><strong><?= al_h($todayCount) ?></strong></div>
            <div class="al-stat"><span>Status changes</span><strong><?= al_h($statusCount) ?></strong></div>
            <div class="al-stat"><span>Tickets touched</span><strong><?= al_h(count($uniqueTickets)) ?></strong></div>
        </section>

        <section class="al-help">
            <i class="fas fa-circle-info"></i>
            <div><strong>Easy mode:</strong> read the sentence first. Click <strong>See change</strong> only when you need proof. Numbers like <strong>2 → 3</strong> are translated automatically, for example <strong>Assigned → In Progress</strong>.</div>
        </section>

        <section class="al-card al-toolbar">
            <input type="search" class="al-input" id="alSearch" placeholder="Search ticket, person, team, action, or changed value...">
            <select class="al-select" id="alActionFilter">
                <option value="">All actions</option>
                <option value="status">Status changes</option>
                <option value="created">Created tickets</option>
                <option value="claimed">Claimed tickets</option>
                <option value="edit">Ticket edits</option>
                <option value="note">Notes</option>
                <option value="notify">Customer notifications</option>
            </select>
            <button type="button" class="al-btn al-btn-dark" id="alClearFilter"><i class="fas fa-broom"></i> Clear</button>
        </section>

        <section class="al-list" id="alList">
            <?php foreach ($logs as $row): ?>
                <?php
                    $easy = al_build_easy_log($row, $statusMap, $valueMaps);
                    $ticket = $row['request_number'] ?: ('#' . ($row['request_id'] ?? ''));
                    $actorName = trim((string)($row['resolved_actor_name'] ?: $row['actor_name'] ?: 'Unknown user'));
                    $actorEmail = trim((string)($row['resolved_actor_email'] ?: $row['actor_email'] ?: ''));
                    $roleLabel = al_role_label($row['resolved_role'] ?? $row['user_role'] ?? '', $row['actor_role_label'] ?? '');
                    $teamBelong = trim((string)($row['team_belong'] ?? '')) ?: 'Unassigned';
                    $dateFull = !empty($row['created_at']) ? date('M d, Y h:i A', strtotime($row['created_at'])) : '';
                    $dateDay = !empty($row['created_at']) ? date('M d, Y', strtotime($row['created_at'])) : '';
                    $dateTime = !empty($row['created_at']) ? date('h:i A', strtotime($row['created_at'])) : '';
                    $payload = [
                        'ticket' => $ticket,
                        'date' => $dateFull,
                        'actor' => $actorName,
                        'role' => $roleLabel,
                        'team' => $teamBelong,
                        'action' => al_action_label($row['action'] ?? ''),
                        'headline' => $easy['headline'],
                        'plain' => $easy['plain'],
                        'fields' => $easy['fields'],
                    ];
                    $payloadJson = htmlspecialchars(json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), ENT_QUOTES, 'UTF-8');
                    $searchBlob = strtolower($ticket . ' ' . $actorName . ' ' . $actorEmail . ' ' . $roleLabel . ' ' . $teamBelong . ' ' . $easy['headline'] . ' ' . $easy['plain'] . ' ' . $easy['before'] . ' ' . $easy['after'] . ' ' . al_action_label($row['action'] ?? ''));
                ?>
                <article class="al-card al-log" data-search="<?= al_h($searchBlob) ?>" data-category="<?= al_h(strtolower($easy['category'])) ?>">
                    <div class="al-time"><?= al_h($dateDay) ?><small><?= al_h($dateTime) ?></small></div>
                    <div class="al-mainline">
                        <div class="al-badges">
                            <span class="al-badge"><?= al_h($easy['category']) ?></span>
                            <span class="al-badge al-ticket"><?= al_h($ticket) ?></span>
                        </div>
                        <div class="al-headline"><?= al_h($easy['headline']) ?></div>
                        <div class="al-plain"><?= al_h($easy['plain']) ?></div>
                    </div>
                    <div class="al-person">
                        <strong><?= al_h($actorName) ?></strong>
                        <small><?= al_h($roleLabel) ?> • <?= al_h($teamBelong) ?></small>
                        <?php if ($actorEmail): ?><small><?= al_h($actorEmail) ?></small><?php endif; ?>
                    </div>
                    <button type="button" class="al-view js-al-view" data-details="<?= $payloadJson ?>"><i class="fas fa-magnifying-glass"></i> See change</button>
                </article>
            <?php endforeach; ?>
            <?php if (!$logs): ?>
                <div class="al-card al-empty">No activity logs found yet.</div>
            <?php endif; ?>
            <div class="al-card al-empty" id="alNoResults" style="display:none;">No logs match your search/filter.</div>
        </section>
    </div>
</main>

<div class="al-modal-backdrop" id="alModalBackdrop" aria-hidden="true">
    <div class="al-modal" role="dialog" aria-modal="true" aria-labelledby="alModalTitle">
        <div class="al-modal-head">
            <div>
                <h2 class="al-modal-title" id="alModalTitle">Change details</h2>
                <div class="al-modal-sub" id="alModalSub"></div>
            </div>
            <button type="button" class="al-close" id="alModalClose" aria-label="Close">&times;</button>
        </div>
        <div class="al-modal-body">
            <div class="al-explain" id="alModalExplain"></div>
            <div class="al-changes" id="alModalChanges"></div>
        </div>
    </div>
</div>

<script>
(function(){
    const search = document.getElementById('alSearch');
    const actionFilter = document.getElementById('alActionFilter');
    const clearBtn = document.getElementById('alClearFilter');
    const items = Array.from(document.querySelectorAll('.al-log'));
    const noResults = document.getElementById('alNoResults');

    function esc(value){
        return String(value ?? '—')
            .replace(/&/g,'&amp;')
            .replace(/</g,'&lt;')
            .replace(/>/g,'&gt;')
            .replace(/"/g,'&quot;')
            .replace(/'/g,'&#039;');
    }

    function applyFilters(){
        const q = (search.value || '').trim().toLowerCase();
        const cat = (actionFilter.value || '').toLowerCase();
        let shown = 0;
        items.forEach(function(item){
            const matchesSearch = !q || (item.dataset.search || '').includes(q);
            const matchesCat = !cat || (item.dataset.category || '') === cat;
            const show = matchesSearch && matchesCat;
            item.style.display = show ? '' : 'none';
            if (show) shown++;
        });
        if (noResults) noResults.style.display = shown === 0 && items.length ? '' : 'none';
    }

    search.addEventListener('input', applyFilters);
    actionFilter.addEventListener('change', applyFilters);
    clearBtn.addEventListener('click', function(){ search.value = ''; actionFilter.value = ''; applyFilters(); });

    const backdrop = document.getElementById('alModalBackdrop');
    const closeBtn = document.getElementById('alModalClose');
    const title = document.getElementById('alModalTitle');
    const sub = document.getElementById('alModalSub');
    const explain = document.getElementById('alModalExplain');
    const changes = document.getElementById('alModalChanges');

    function openModal(payload){
        title.textContent = payload.headline || 'Change details';
        sub.textContent = [payload.ticket, payload.date, payload.actor, payload.role, payload.team].filter(Boolean).join(' • ');
        explain.textContent = payload.plain || 'This log has no explanation saved.';
        changes.innerHTML = '';

        (payload.fields || []).forEach(function(field){
            const changedClass = field.changed ? ' changed' : '';
            changes.insertAdjacentHTML('beforeend', `
                <div class="al-change${changedClass}">
                    <div class="al-change-field">${esc(field.field)}</div>
                    <div class="al-change-grid">
                        <div>
                            <div class="al-label">Before</div>
                            <div class="al-value al-old">${esc(field.old)}</div>
                        </div>
                        <div>
                            <div class="al-label">After</div>
                            <div class="al-value al-new">${esc(field.new)}</div>
                        </div>
                    </div>
                </div>
            `);
        });
        if (!changes.innerHTML) changes.innerHTML = '<div class="al-empty">No detail saved for this activity.</div>';
        backdrop.classList.add('show');
        backdrop.setAttribute('aria-hidden','false');
    }

    function closeModal(){
        backdrop.classList.remove('show');
        backdrop.setAttribute('aria-hidden','true');
    }

    document.querySelectorAll('.js-al-view').forEach(function(btn){
        btn.addEventListener('click', function(){
            try { openModal(JSON.parse(this.dataset.details || '{}')); }
            catch(e) { openModal({headline:'Unable to read details', plain:'The saved log detail could not be opened.', fields:[]}); }
        });
    });
    closeBtn.addEventListener('click', closeModal);
    backdrop.addEventListener('click', function(e){ if (e.target === backdrop) closeModal(); });
    document.addEventListener('keydown', function(e){ if (e.key === 'Escape') closeModal(); });
})();
</script>
</body>
</html>
