<?php

namespace Core\App\Models;

use PDO;

class AdminActivityModel
{
    private PDO $db;

    public function __construct()
    {
        $this->db = \db();
    }

    /**
     * Log a login or logout event
     */
    public function log(int $adminId, string $action, string $ip = '', string $userAgent = ''): void
    {
        $stmt = $this->db->prepare("
            INSERT INTO admin_activity_log (admin_id, action, ip_address, user_agent)
            VALUES (:admin_id, :action, :ip, :ua)
        ");
        $stmt->execute([
            ':admin_id' => $adminId,
            ':action'   => $action,
            ':ip'       => substr($ip, 0, 45),
            ':ua'       => substr($userAgent, 0, 255),
        ]);
    }

    /**
     * Get activity log paginated
     */
    public function getLog(int $limit = 100, int $offset = 0, ?int $adminId = null): array
    {
        $where = $adminId ? "WHERE l.admin_id = :admin_id" : "";
        $params = [];
        if ($adminId) $params[':admin_id'] = $adminId;

        $sql = "
            SELECT l.*, a.username, a.avatar, a.role
            FROM admin_activity_log l
            JOIN admins a ON a.id = l.admin_id
            {$where}
            ORDER BY l.created_at DESC
            LIMIT :lim OFFSET :off
        ";
        $stmt = $this->db->prepare($sql);
        foreach ($params as $k => $v) {
            $stmt->bindValue($k, $v, PDO::PARAM_INT);
        }
        $stmt->bindValue(':lim', $limit,  PDO::PARAM_INT);
        $stmt->bindValue(':off', $offset, PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    /**
     * Get current online admins (last_seen_at within 5 minutes)
     */
    public function getOnlineAdmins(): array
    {
        $stmt = $this->db->query("
            SELECT id, username, avatar, role, last_seen_at
            FROM admins
            WHERE is_active = 1
              AND last_seen_at >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)
            ORDER BY last_seen_at DESC
        ");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    /**
     * Update last_seen_at for an admin (heartbeat)
     */
    public function updatePresence(int $adminId): void
    {
        $stmt = $this->db->prepare("
            UPDATE admins SET last_seen_at = NOW() WHERE id = :id
        ");
        $stmt->execute([':id' => $adminId]);
    }

    /**
     * Get all admins with their online status
     */
    public function getAllWithPresence(): array
    {
        $stmt = $this->db->query("
            SELECT id, username, avatar, role, is_active, last_seen_at,
                   CASE WHEN last_seen_at >= DATE_SUB(NOW(), INTERVAL 5 MINUTE) THEN 1 ELSE 0 END AS is_online
            FROM admins
            WHERE is_active = 1
            ORDER BY is_online DESC, username ASC
        ");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    /**
     * Login/logout summary per admin (for stats)
     */
    public function getSummaryPerAdmin(int $days = 30): array
    {
        $stmt = $this->db->prepare("
            SELECT a.id, a.username, a.role,
                   COUNT(CASE WHEN l.action='login'  THEN 1 END) AS login_count,
                   MAX(CASE WHEN l.action='login'  THEN l.created_at END) AS last_login,
                   MAX(CASE WHEN l.action='logout' THEN l.created_at END) AS last_logout
            FROM admins a
            LEFT JOIN admin_activity_log l ON l.admin_id = a.id
                AND l.created_at >= DATE_SUB(NOW(), INTERVAL :days DAY)
            WHERE a.is_active = 1
            GROUP BY a.id
            ORDER BY a.username ASC
        ");
        $stmt->bindValue(':days', $days, PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
}
