<?php
/**
 * TOPBD — Ranking Engine & Calculation Module
 */

require_once __DIR__ . '/db.php';
require_once __DIR__ . '/functions.php';

class RankingEngine {
    /**
     * Get Ranked Listings with Filters and Pagination
     */
    public static function getRankings(string $timeFilter = 'all_time', string $categorySlug = 'all', int $page = 1, int $perPage = 50): array {
        $db = get_db();
        $params = [];
        $where = ["l.is_active = 1"];

        // Category Filter
        if ($categorySlug !== 'all' && !empty($categorySlug)) {
            $where[] = "c.slug = ?";
            $params[] = $categorySlug;
        }

        // Today Filter
        if ($timeFilter === 'today') {
            $where[] = "DATE(l.last_bid_at) = CURDATE()";
        }

        $whereClause = implode(" AND ", $where);

        // Count Total
        $countSql = "SELECT COUNT(*) FROM listings l 
                     JOIN categories c ON l.category_id = c.id 
                     WHERE {$whereClause}";
        $stmt = $db->prepare($countSql);
        $stmt->execute($params);
        $totalItems = (int)$stmt->fetchColumn();

        $totalPages = max(1, (int)ceil($totalItems / $perPage));
        $offset = ($page - 1) * $perPage;

        // Fetch Ranked Listings (Order: current_bid DESC, last_bid_at ASC, id ASC)
        $sql = "SELECT l.*, c.name AS category_name, c.slug AS category_slug, c.icon AS category_icon,
                (SELECT COUNT(*) + 1 FROM listings sub 
                 WHERE sub.category_id = l.category_id AND sub.is_active = 1 
                 AND (sub.current_bid > l.current_bid OR (sub.current_bid = l.current_bid AND sub.last_bid_at < l.last_bid_at))) AS category_rank
                FROM listings l
                JOIN categories c ON l.category_id = c.id
                WHERE {$whereClause}
                ORDER BY l.current_bid DESC, l.last_bid_at ASC, l.id ASC
                LIMIT {$perPage} OFFSET {$offset}";

        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        $rows = $stmt->fetchAll();

        // Assign Rank Numbers based on overall page offset
        $ranked = [];
        foreach ($rows as $index => $row) {
            $row['rank'] = $offset + $index + 1;
            $ranked[] = $row;
        }

        return [
            'listings' => $ranked,
            'total' => $totalItems,
            'totalPages' => $totalPages,
            'currentPage' => $page,
            'perPage' => $perPage,
        ];
    }

    /**
     * Get Overall #1 Top Listing for Hero Section
     */
    public static function getTopListing(): ?array {
        $db = get_db();
        $stmt = $db->query("SELECT l.*, c.name AS category_name 
                            FROM listings l 
                            JOIN categories c ON l.category_id = c.id 
                            WHERE l.is_active = 1 
                            ORDER BY l.current_bid DESC, l.last_bid_at ASC, l.id ASC 
                            LIMIT 1");
        return $stmt->fetch() ?: null;
    }

    /**
     * Get Total Money Generated (Sum of successful verified payments)
     */
    public static function getTotalGenerated(): float {
        $db = get_db();
        $stmt = $db->query("SELECT COALESCE(SUM(amount), 0) FROM payments WHERE status = 'success'");
        return (float)$stmt->fetchColumn();
    }

    /**
     * Heartbeat live visitor counter
     */
    public static function getLiveVisitors(int $timeoutSeconds = 180): int {
        $db = get_db();
        // Remove stale sessions
        $cleanup = $db->prepare("DELETE FROM visitors WHERE last_seen < (NOW() - INTERVAL ? SECOND)");
        $cleanup->execute([$timeoutSeconds]);

        // Count active
        $stmt = $db->query("SELECT COUNT(*) FROM visitors");
        $count = (int)$stmt->fetchColumn();
        return max(0, $count);
    }
}
