<?php
// src/controllers/RankingController.php
//
// Sistema de Ranking de Amigos
// -----------------------------
// Puntuación por amigo (interacciones hacia TI):
//   • +1 punto por cada like que te da en tus publicaciones.
//   • +2 puntos por cada comentario que te deja.
//   • +3 puntos por cada etiqueta que te hace (@tuUsuario) en sus publicaciones.
// Total = (likes × 1) + (comentarios × 2) + (etiquetas × 3)

class RankingController
{
    public static function index($db)
    {
        if (empty($_SESSION['user']['id'])) {
            redirect('./?r=login');
            return;
        }

        $user_id   = $_SESSION['user']['id'];
        $friends   = self::getUserFriends($db, $user_id);
        $ranking   = [];
        $birthdays = [];

        if (!empty($friends)) {
            foreach ($friends as $friend) {
                // Ahora devolvemos el desglose (likes/comments/tags) + total
                $stats = self::calculateInteractionBreakdown($db, $user_id, $friend['id']);
                $ranking[] = [
                    'id'             => $friend['id'],
                    'username'       => $friend['username'],
                    'avatar_url'     => $friend['avatar_url'],
                    'likes_count'    => (int)$stats['likes'],
                    'comments_count' => (int)$stats['comments'],
                    'tags_count'     => (int)$stats['tags'],
                    'points'         => (int)$stats['total'],
                ];
            }
            usort($ranking, fn($a, $b) => $b['points'] <=> $a['points']);
            $birthdays = self::getUpcomingBirthdays($db, $user_id);
        }

        view('ranking', [
            'ranking'   => $ranking,
            'birthdays' => $birthdays,
            'friends'   => $friends,
        ]);
    }

    private static function getUserFriends(PDO $db, string $user_id): array
    {
        // Amigos aceptados (evita placeholders repetidos)
        $stmt = $db->prepare("
            SELECT CASE
                WHEN user1_id = :uid1 THEN user2_id
                WHEN user2_id = :uid2 THEN user1_id
            END AS friend_id
            FROM friends
            WHERE (user1_id = :uid3 OR user2_id = :uid4)
              AND status = 'accepted'
        ");
        $stmt->execute([
            ':uid1' => $user_id,
            ':uid2' => $user_id,
            ':uid3' => $user_id,
            ':uid4' => $user_id,
        ]);
        $friend_ids = array_values(array_filter($stmt->fetchAll(PDO::FETCH_COLUMN)));

        if (empty($friend_ids)) {
            return [];
        }

        $in = implode(',', array_fill(0, count($friend_ids), '?'));
        $stmt = $db->prepare("
            SELECT id, username, avatar_url, birth_date
            FROM users
            WHERE id IN ($in)
            ORDER BY username
        ");
        $stmt->execute($friend_ids);
        return $stmt->fetchAll() ?: [];
    }

    /**
     * Devuelve desglose de interacciones del amigo hacia mí:
     * ['likes' => n, 'comments' => n, 'tags' => n, 'total' => n]
     */
    private static function calculateInteractionBreakdown(PDO $db, string $me, string $friend): array
    {
        $likes = 0; $comments = 0; $tags = 0;

        // Likes del amigo en MIS publicaciones
        $q1 = $db->prepare("
            SELECT COUNT(*) 
            FROM likes l
            JOIN posts p ON p.id = l.post_id
            WHERE p.author_id = :me AND l.user_id = :friend
        ");
        $q1->execute([':me' => $me, ':friend' => $friend]);
        $likes = (int)$q1->fetchColumn();

        // Comentarios del amigo en MIS publicaciones
        $q2 = $db->prepare("
            SELECT COUNT(*)
            FROM comments c
            JOIN posts p ON p.id = c.post_id
            WHERE p.author_id = :me AND c.user_id = :friend
        ");
        $q2->execute([':me' => $me, ':friend' => $friend]);
        $comments = (int)$q2->fetchColumn();

        // Etiquetas del amigo hacia mí (t.name = mi username) en SUS publicaciones
        $usernameStmt = $db->prepare("SELECT username FROM users WHERE id = ?");
        $usernameStmt->execute([$me]);
        $myUsername = (string)$usernameStmt->fetchColumn();

        if ($myUsername !== '') {
            $q3 = $db->prepare("
                SELECT COUNT(*)
                FROM tags t
                JOIN posts p ON p.id = t.post_id
                WHERE p.author_id = :friend AND t.name = :myuser
            ");
            $q3->execute([':friend' => $friend, ':myuser' => $myUsername]);
            $tags = (int)$q3->fetchColumn();
        }

        $total = $likes * 1 + $comments * 2 + $tags * 3;

        return [
            'likes'    => $likes,
            'comments' => $comments,
            'tags'     => $tags,
            'total'    => $total,
        ];
    }

    private static function getUpcomingBirthdays(PDO $db, string $user_id): array
    {
        $friends = self::getUserFriends($db, $user_id);
        if (empty($friends)) {
            return [];
        }

        $ids = array_column($friends, 'id');
        $in  = implode(',', array_fill(0, count($ids), '?'));

        $sql = "
            SELECT
                u.id,
                u.username,
                u.avatar_url,
                u.birth_date,
                CASE
                  WHEN DATE_FORMAT(u.birth_date, '%m-%d') < DATE_FORMAT(CURDATE(), '%m-%d')
                    THEN STR_TO_DATE(CONCAT(YEAR(CURDATE())+1, DATE_FORMAT(u.birth_date, '-%m-%d')), '%Y-%m-%d')
                  ELSE STR_TO_DATE(CONCAT(YEAR(CURDATE()),     DATE_FORMAT(u.birth_date, '-%m-%d')), '%Y-%m-%d')
                END AS next_birthday
            FROM users u
            WHERE u.id IN ($in)
              AND u.birth_date IS NOT NULL
            HAVING DATEDIFF(next_birthday, CURDATE()) BETWEEN 0 AND 30
            ORDER BY next_birthday ASC
        ";
        $stmt = $db->prepare($sql);
        $stmt->execute($ids);
        return $stmt->fetchAll() ?: [];
    }
}
