const request = require('supertest');
const { app } = require('../../backend/server');
const { cleanDb, seedGame, seedSession, seedSessionGame, seedVote } = require('../helpers/test-utils');

describe('GET /api/sessions/:id/votes', () => {
  beforeEach(() => {
    cleanDb();
  });

  test('returns per-game vote breakdown for a session', async () => {
    const game1 = seedGame({ title: 'Quiplash 3', pack_name: 'Party Pack 7' });
    const game2 = seedGame({ title: 'Drawful 2', pack_name: 'Party Pack 3' });
    const session = seedSession({ is_active: 1 });
    seedSessionGame(session.id, game1.id);
    seedSessionGame(session.id, game2.id);

    seedVote(session.id, game1.id, 'user1', 'up');
    seedVote(session.id, game1.id, 'user2', 'up');
    seedVote(session.id, game1.id, 'user3', 'down');
    seedVote(session.id, game2.id, 'user1', 'down');

    const res = await request(app).get(`/api/sessions/${session.id}/votes`);

    expect(res.status).toBe(200);
    expect(res.body.session_id).toBe(session.id);
    expect(res.body.votes).toHaveLength(2);

    const q3 = res.body.votes.find((v) => v.game_id === game1.id);
    expect(q3.title).toBe('Quiplash 3');
    expect(q3.pack_name).toBe('Party Pack 7');
    expect(q3.upvotes).toBe(2);
    expect(q3.downvotes).toBe(1);
    expect(q3.net_score).toBe(1);
    expect(q3.total_votes).toBe(3);

    const d2 = res.body.votes.find((v) => v.game_id === game2.id);
    expect(d2.upvotes).toBe(0);
    expect(d2.downvotes).toBe(1);
    expect(d2.net_score).toBe(-1);
    expect(d2.total_votes).toBe(1);
  });

  test('returns empty votes array when session has no votes', async () => {
    const session = seedSession({ is_active: 1 });

    const res = await request(app).get(`/api/sessions/${session.id}/votes`);

    expect(res.status).toBe(200);
    expect(res.body.session_id).toBe(session.id);
    expect(res.body.votes).toEqual([]);
  });

  test('returns 404 for nonexistent session', async () => {
    const res = await request(app).get('/api/sessions/99999/votes');

    expect(res.status).toBe(404);
    expect(res.body.error).toBe('Session not found');
  });

  test('only includes votes from the requested session', async () => {
    const game = seedGame({ title: 'Quiplash 3' });
    const session1 = seedSession({ is_active: 0 });
    const session2 = seedSession({ is_active: 1 });
    seedSessionGame(session1.id, game.id);
    seedSessionGame(session2.id, game.id);

    seedVote(session1.id, game.id, 'user1', 'up');
    seedVote(session1.id, game.id, 'user2', 'up');
    seedVote(session2.id, game.id, 'user3', 'down');

    const res = await request(app).get(`/api/sessions/${session1.id}/votes`);

    expect(res.body.votes).toHaveLength(1);
    expect(res.body.votes[0].upvotes).toBe(2);
    expect(res.body.votes[0].downvotes).toBe(0);
  });

  test('results are ordered by net_score descending', async () => {
    const game1 = seedGame({ title: 'Good Game' });
    const game2 = seedGame({ title: 'Bad Game' });
    const session = seedSession({ is_active: 1 });
    seedSessionGame(session.id, game1.id);
    seedSessionGame(session.id, game2.id);

    seedVote(session.id, game2.id, 'user1', 'down');
    seedVote(session.id, game2.id, 'user2', 'down');
    seedVote(session.id, game1.id, 'user1', 'up');

    const res = await request(app).get(`/api/sessions/${session.id}/votes`);

    expect(res.body.votes[0].title).toBe('Good Game');
    expect(res.body.votes[1].title).toBe('Bad Game');
  });
});
