import { describe, it, expect, beforeAll, afterAll, vi } from "vitest";
import {
  getPoolSharkTables,
  getPoolSharkTableWithMatch,
  joinPoolSharkTable,
  completePoolSharkMatch,
  getPoolSharkLeaderboard,
  getUserPoolSharkStats,
} from "./poolShark.ts";

describe("Pool Shark Backend", () => {
  describe("getPoolSharkTables", () => {
    it("should return all active Pool Shark tables", async () => {
      const tables = await getPoolSharkTables();
      expect(Array.isArray(tables)).toBe(true);
      expect(tables.length).toBeGreaterThan(0);
      
      // Verify table structure
      tables.forEach(table => {
        expect(table).toHaveProperty("id");
        expect(table).toHaveProperty("name");
        expect(table).toHaveProperty("entryFee");
        expect(table).toHaveProperty("maxPlayers");
        expect(table).toHaveProperty("status");
        expect(table.status).toBe("active");
      });
    });
  });

  describe("getPoolSharkTableWithMatch", () => {
    it("should return null for non-existent table", async () => {
      const result = await getPoolSharkTableWithMatch(99999);
      expect(result).toBeNull();
    });

    it("should return table details with match info", async () => {
      const tables = await getPoolSharkTables();
      if (tables.length > 0) {
        const result = await getPoolSharkTableWithMatch(tables[0].id);
        expect(result).not.toBeNull();
        if (result) {
          expect(result).toHaveProperty("table");
          expect(result).toHaveProperty("currentMatch");
          expect(result).toHaveProperty("participants");
          expect(result).toHaveProperty("waitingList");
          expect(Array.isArray(result.participants)).toBe(true);
          expect(Array.isArray(result.waitingList)).toBe(true);
        }
      }
    });
  });

  describe("getPoolSharkLeaderboard", () => {
    it("should return leaderboard with default pagination", async () => {
      const leaderboard = await getPoolSharkLeaderboard();
      expect(Array.isArray(leaderboard)).toBe(true);
      expect(leaderboard.length).toBeLessThanOrEqual(100);
    });

    it("should respect limit parameter", async () => {
      const leaderboard = await getPoolSharkLeaderboard(10, 0);
      expect(leaderboard.length).toBeLessThanOrEqual(10);
    });

    it("should have correct leaderboard structure", async () => {
      const leaderboard = await getPoolSharkLeaderboard(5, 0);
      leaderboard.forEach(entry => {
        expect(entry).toHaveProperty("userId");
        expect(entry).toHaveProperty("totalMatches");
        expect(entry).toHaveProperty("totalWins");
        expect(entry).toHaveProperty("totalLosses");
        expect(entry).toHaveProperty("winRate");
        expect(entry).toHaveProperty("totalPrizeWon");
        expect(entry).toHaveProperty("rank");
        
        // Verify data types
        expect(typeof entry.userId).toBe("number");
        expect(typeof entry.totalMatches).toBe("number");
        expect(typeof entry.totalWins).toBe("number");
        expect(typeof entry.rank).toBe("number");
      });
    });
  });

  describe("getUserPoolSharkStats", () => {
    it("should return user stats with leaderboard and achievements", async () => {
      // Note: This test requires a user to exist in the database
      // Using a mock user ID for demonstration
      const userId = 1;
      
      try {
        const stats = await getUserPoolSharkStats(userId);
        expect(stats).toHaveProperty("leaderboard");
        expect(stats).toHaveProperty("achievements");
        expect(Array.isArray(stats.achievements)).toBe(true);
        
        if (stats.leaderboard) {
          expect(stats.leaderboard).toHaveProperty("userId");
          expect(stats.leaderboard).toHaveProperty("totalWins");
          expect(stats.leaderboard).toHaveProperty("totalMatches");
          expect(stats.leaderboard).toHaveProperty("winRate");
        }
      } catch (error) {
        // User may not exist in test database
        expect(error).toBeDefined();
      }
    });
  });

  describe("Pool Shark Integration", () => {
    it("should have proper table configuration", async () => {
      const tables = await getPoolSharkTables();
      
      // Verify we have the 10 branded tables
      expect(tables.length).toBeGreaterThanOrEqual(1);
      
      // Verify entry fees range from 1-100 SC
      tables.forEach(table => {
        const entryFee = Number(table.entryFee);
        expect(entryFee).toBeGreaterThanOrEqual(1);
        expect(entryFee).toBeLessThanOrEqual(100);
        
        // Verify prize multiplier is reasonable
        const prizeMultiplier = Number(table.prizeMultiplier);
        expect(prizeMultiplier).toBeGreaterThan(1);
        expect(prizeMultiplier).toBeLessThanOrEqual(2);
        
        // Verify max players is 2 (1v1) or 4 (team play)
        expect([2, 4]).toContain(table.maxPlayers);
      });
    });

    it("should have achievement types defined", async () => {
      const tables = await getPoolSharkTables();
      if (tables.length > 0) {
        const tableDetails = await getPoolSharkTableWithMatch(tables[0].id);
        // Just verify the structure is accessible
        expect(tableDetails).toBeDefined();
      }
    });
  });
});
