import { describe, it, expect, beforeEach } from 'vitest';
import type Database from 'better-sqlite3';
import { getUnfinishedParticipants } from '@/lib/restaurant-filter';
import { createTestDb } from '@/lib/test-helpers';

// Testet den harten Joker-Gate: Ein Teilnehmer gilt erst als "fertig", wenn er
// alle Karten SEINES Stapels geswipet hat - nicht alle Restaurants im Umkreis.
// Der Stapel ist begrenzt (40/60 Karten), der Gate muss dieselbe Begrenzung
// verwenden, sonst kann z.B. eine Solo-Session den Joker nie ziehen.
describe('getUnfinishedParticipants', () => {
  let db: Database.Database;

  beforeEach(() => {
    db = createTestDb();
  });

  function setupSession() {
    const s = db
      .prepare("INSERT INTO sessions (code, city, status) VALUES (?, 'Teststadt', 'active')")
      .run(`S${Date.now()}-${Math.random()}`);
    const sessionId = Number(s.lastInsertRowid);
    const p = db
      .prepare('INSERT INTO participants (session_id, anonymous_id, is_active) VALUES (?, ?, 1)')
      .run(sessionId, `anon-${Math.random()}`);
    const participantId = Number(p.lastInsertRowid);
    return { sessionId, participantId };
  }

  function addRestaurant(name: string) {
    const r = db.prepare('INSERT INTO restaurants (name) VALUES (?)').run(name);
    return Number(r.lastInsertRowid);
  }

  function swipe(sessionId: number, participantId: number, restaurantId: number) {
    db.prepare(
      'INSERT INTO swipes (session_id, participant_id, restaurant_id, direction) VALUES (?, ?, ?, ?)'
    ).run(sessionId, participantId, restaurantId, 'yes');
  }

  function sessionRow(sessionId: number) {
    return db.prepare('SELECT * FROM sessions WHERE id = ?').get(sessionId) as any;
  }

  it('gilt als fertig, wenn alle 40 Stapel-Karten geswipet wurden (auch bei >40 im Umkreis)', () => {
    const { sessionId, participantId } = setupSession();
    const ids: number[] = [];
    for (let i = 0; i < 50; i++) ids.push(addRestaurant(`Restaurant ${i}`));

    // Der Stapel enthaelt nur die ersten 40 - die swiped der Teilnehmer alle.
    for (let i = 0; i < 40; i++) swipe(sessionId, participantId, ids[i]);

    const unfinished = getUnfinishedParticipants(db, sessionRow(sessionId));
    expect(unfinished).toEqual([]);
  });

  it('gilt als unfertig, wenn eine Stapel-Karte noch nicht geswipet wurde', () => {
    const { sessionId, participantId } = setupSession();
    const ids: number[] = [];
    for (let i = 0; i < 50; i++) ids.push(addRestaurant(`Restaurant ${i}`));

    // Nur 39 von 40 Stapel-Karten geswipet.
    for (let i = 0; i < 39; i++) swipe(sessionId, participantId, ids[i]);

    const unfinished = getUnfinishedParticipants(db, sessionRow(sessionId));
    expect(unfinished.map((p) => p.id)).toEqual([participantId]);
  });
});
