<?php
/**
 * rating_helpers.php — Shared rating functions for SaniBook
 * Version: 1.0.0
 */

/**
 * Get average rating and count for an item.
 *
 * @param mysqli $conn       Database connection
 * @param string $item_type  'submission' or 'content'
 * @param int    $item_id    The item's ID
 * @return array             ['avg' => float, 'count' => int]
 */
function get_item_rating(mysqli $conn, string $item_type, int $item_id): array
{
    $stmt = $conn->prepare("SELECT AVG(rating) AS avg_rating, COUNT(*) AS total FROM ratings WHERE item_type = ? AND item_id = ?");
    $stmt->bind_param("si", $item_type, $item_id);
    $stmt->execute();
    $result = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    return [
        'avg' => round((float) ($result['avg_rating'] ?? 0), 1),
        'count' => (int) ($result['total'] ?? 0),
    ];
}

/**
 * Get a specific user's rating for an item.
 *
 * @param mysqli $conn       Database connection
 * @param int    $user_id    The user's ID
 * @param string $item_type  'submission' or 'content'
 * @param int    $item_id    The item's ID
 * @return int               Rating 1-5, or 0 if not yet rated
 */
function get_user_rating(mysqli $conn, int $user_id, string $item_type, int $item_id): int
{
    $stmt = $conn->prepare("SELECT rating FROM ratings WHERE user_id = ? AND item_type = ? AND item_id = ?");
    $stmt->bind_param("isi", $user_id, $item_type, $item_id);
    $stmt->execute();
    $result = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    return (int) ($result['rating'] ?? 0);
}

/**
 * Batch-fetch average ratings for multiple items of the same type.
 *
 * @param mysqli $conn       Database connection
 * @param string $item_type  'submission' or 'content'
 * @param array  $item_ids   Array of item IDs
 * @return array             Keyed by item_id => ['avg' => float, 'count' => int]
 */
function get_batch_ratings(mysqli $conn, string $item_type, array $item_ids): array
{
    $ratings = [];
    if (empty($item_ids))
        return $ratings;

    $placeholders = implode(',', array_fill(0, count($item_ids), '?'));
    $types = str_repeat('i', count($item_ids));

    $sql = "SELECT item_id, AVG(rating) AS avg_rating, COUNT(*) AS total
            FROM ratings
            WHERE item_type = ? AND item_id IN ($placeholders)
            GROUP BY item_id";

    $stmt = $conn->prepare($sql);
    $params = array_merge([$item_type], $item_ids);
    $bind_types = 's' . $types;
    $stmt->bind_param($bind_types, ...$params);
    $stmt->execute();
    $result = $stmt->get_result();

    while ($row = $result->fetch_assoc()) {
        $ratings[(int) $row['item_id']] = [
            'avg' => round((float) $row['avg_rating'], 1),
            'count' => (int) $row['total'],
        ];
    }
    $stmt->close();

    // Fill in zeros for items with no ratings
    foreach ($item_ids as $id) {
        if (!isset($ratings[$id])) {
            $ratings[$id] = ['avg' => 0, 'count' => 0];
        }
    }
    return $ratings;
}

/**
 * Batch-fetch a user's ratings for multiple items.
 *
 * @param mysqli $conn       Database connection
 * @param int    $user_id    The user's ID
 * @param string $item_type  'submission' or 'content'
 * @param array  $item_ids   Array of item IDs
 * @return array             Keyed by item_id => int (rating)
 */
function get_batch_user_ratings(mysqli $conn, int $user_id, string $item_type, array $item_ids): array
{
    $user_ratings = [];
    if (empty($item_ids) || $user_id <= 0)
        return $user_ratings;

    $placeholders = implode(',', array_fill(0, count($item_ids), '?'));
    $types = str_repeat('i', count($item_ids));

    $sql = "SELECT item_id, rating FROM ratings WHERE user_id = ? AND item_type = ? AND item_id IN ($placeholders)";
    $stmt = $conn->prepare($sql);
    $params = array_merge([$user_id, $item_type], $item_ids);
    $bind_types = 'is' . $types;
    $stmt->bind_param($bind_types, ...$params);
    $stmt->execute();
    $result = $stmt->get_result();

    while ($row = $result->fetch_assoc()) {
        $user_ratings[(int) $row['item_id']] = (int) $row['rating'];
    }
    $stmt->close();

    foreach ($item_ids as $id) {
        if (!isset($user_ratings[$id])) {
            $user_ratings[$id] = 0;
        }
    }
    return $user_ratings;
}

/**
 * Render interactive star rating HTML.
 *
 * @param float  $avg          Average rating
 * @param int    $count        Total number of ratings
 * @param string $item_type    'submission' or 'content'
 * @param int    $item_id      The item's ID
 * @param int    $user_rating  Current user's rating (0 if none)
 * @param bool   $is_logged_in Whether user is logged in
 * @return string              HTML markup
 */
function render_stars(float $avg, int $count, string $item_type, int $item_id, int $user_rating, bool $is_logged_in): string
{
    $html = '<div class="star-rating-widget" data-item-type="' . esc_attr($item_type) . '" data-item-id="' . esc_attr((string) $item_id) . '">';
    $html .= '<div class="star-rating-stars">';

    for ($i = 1; $i <= 5; $i++) {
        $filled = ($i <= round($avg)) ? 'filled' : '';
        $user_filled = ($i <= $user_rating) ? 'user-rated' : '';
        $clickable = $is_logged_in ? 'clickable' : '';
        $title = $is_logged_in ? "Rate $i star" . ($i > 1 ? 's' : '') : 'Login to rate';

        $html .= '<span class="star ' . trim("$filled $user_filled $clickable") . '" data-value="' . $i . '" title="' . esc_attr($title) . '">';
        $html .= '<i class="fa' . ($i <= $user_rating ? 's' : ($i <= round($avg) ? 's' : 'r')) . ' fa-star"></i>';
        $html .= '</span>';
    }

    $html .= '</div>';
    $html .= '<span class="star-rating-info">' . esc_html((string) $avg) . ' (' . esc_html((string) $count) . ')</span>';
    $html .= '</div>';

    return $html;
}


