import { describe, it, expect, beforeEach, vi } from "vitest";
import { activityFeedRouter } from "./activityFeed.ts";
import * as activityService from "../services/activityFeedService.ts";

// Mock the activity service
vi.mock("../services/activityFeedService", () => ({
  getActivityFeed: vi.fn(),
  getPlayerActivity: vi.fn(),
  getActivityByType: vi.fn(),
  getHighValueWins: vi.fn(),
  getActivityStats: vi.fn(),
  recordGameWin: vi.fn(),
  recordAchievement: vi.fn(),
  recordTournamentWin: vi.fn(),
  recordMilestone: vi.fn(),
}));

describe("activityFeedRouter", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("should have getFeed procedure", () => {
    expect(activityFeedRouter._def.procedures.getFeed).toBeDefined();
  });

  it("should have getPlayerActivity procedure", () => {
    expect(activityFeedRouter._def.procedures.getPlayerActivity).toBeDefined();
  });

  it("should have getByType procedure", () => {
    expect(activityFeedRouter._def.procedures.getByType).toBeDefined();
  });

  it("should have getHighValueWins procedure", () => {
    expect(activityFeedRouter._def.procedures.getHighValueWins).toBeDefined();
  });

  it("should have getStats procedure", () => {
    expect(activityFeedRouter._def.procedures.getStats).toBeDefined();
  });

  it("should have recordWin procedure", () => {
    expect(activityFeedRouter._def.procedures.recordWin).toBeDefined();
  });

  it("should have recordAchievement procedure", () => {
    expect(activityFeedRouter._def.procedures.recordAchievement).toBeDefined();
  });

  it("should have recordTournamentWin procedure", () => {
    expect(activityFeedRouter._def.procedures.recordTournamentWin).toBeDefined();
  });

  it("should have recordMilestone procedure", () => {
    expect(activityFeedRouter._def.procedures.recordMilestone).toBeDefined();
  });

  it("getFeed should call activityService.getActivityFeed", async () => {
    const mockActivities = [
      {
        id: 1,
        type: "win" as const,
        playerId: 1,
        playerName: "TestPlayer",
        gameId: "game1",
        gameName: "Golden Dragon",
        winAmount: 5000,
        multiplier: 1,
        timestamp: new Date(),
      },
    ];

    vi.mocked(activityService.getActivityFeed).mockResolvedValue(mockActivities);

    const result = await activityService.getActivityFeed(50);
    expect(result).toEqual(mockActivities);
    expect(activityService.getActivityFeed).toHaveBeenCalledWith(50);
  });

  it("getPlayerActivity should call activityService.getPlayerActivity", async () => {
    const mockActivities = [
      {
        id: 1,
        type: "win" as const,
        playerId: 1,
        playerName: "TestPlayer",
        gameId: "game1",
        gameName: "Golden Dragon",
        winAmount: 5000,
        multiplier: 1,
        timestamp: new Date(),
      },
    ];

    vi.mocked(activityService.getPlayerActivity).mockResolvedValue(mockActivities);

    const result = await activityService.getPlayerActivity(1, 20);
    expect(result).toEqual(mockActivities);
    expect(activityService.getPlayerActivity).toHaveBeenCalledWith(1, 20);
  });

  it("getActivityByType should call activityService.getActivityByType", async () => {
    const mockActivities = [
      {
        id: 1,
        type: "achievement" as const,
        playerId: 1,
        playerName: "TestPlayer",
        achievementId: "ach1",
        achievementName: "First Win",
        achievementIcon: "🏆",
        timestamp: new Date(),
      },
    ];

    vi.mocked(activityService.getActivityByType).mockResolvedValue(mockActivities);

    const result = await activityService.getActivityByType("achievement", 50);
    expect(result).toEqual(mockActivities);
    expect(activityService.getActivityByType).toHaveBeenCalledWith("achievement", 50);
  });

  it("getHighValueWins should call activityService.getHighValueWins", async () => {
    const mockWins = [
      {
        id: 1,
        type: "win" as const,
        playerId: 1,
        playerName: "TestPlayer",
        gameId: "game1",
        gameName: "Golden Dragon",
        winAmount: 50000,
        multiplier: 5,
        timestamp: new Date(),
      },
    ];

    vi.mocked(activityService.getHighValueWins).mockResolvedValue(mockWins);

    const result = await activityService.getHighValueWins(1000, 20);
    expect(result).toEqual(mockWins);
    expect(activityService.getHighValueWins).toHaveBeenCalledWith(1000, 20);
  });

  it("getStats should return activity statistics", async () => {
    const mockStats = {
      totalActivities: 100,
      totalWins: 50,
      totalAchievements: 30,
      totalTournaments: 15,
      totalMilestones: 5,
      totalWinAmount: 500000,
    };

    vi.mocked(activityService.getActivityStats).mockResolvedValue(mockStats);

    const result = await activityService.getActivityStats();
    expect(result).toEqual(mockStats);
    expect(activityService.getActivityStats).toHaveBeenCalled();
  });

  it("recordGameWin should return success", async () => {
    const mockActivity = {
      id: 1,
      type: "win" as const,
      playerId: 1,
      playerName: "TestPlayer",
      gameId: "game1",
      gameName: "Golden Dragon",
      winAmount: 5000,
      multiplier: 1,
      timestamp: new Date(),
    };

    vi.mocked(activityService.recordGameWin).mockResolvedValue(mockActivity);

    const result = await activityService.recordGameWin(
      1,
      "TestPlayer",
      undefined,
      "game1",
      "Golden Dragon",
      5000,
      1
    );

    expect(result).toEqual(mockActivity);
    expect(activityService.recordGameWin).toHaveBeenCalledWith(
      1,
      "TestPlayer",
      undefined,
      "game1",
      "Golden Dragon",
      5000,
      1
    );
  });

  it("recordAchievement should return success", async () => {
    const mockActivity = {
      id: 1,
      type: "achievement" as const,
      playerId: 1,
      playerName: "TestPlayer",
      achievementId: "ach1",
      achievementName: "First Win",
      achievementIcon: "🏆",
      timestamp: new Date(),
    };

    vi.mocked(activityService.recordAchievement).mockResolvedValue(mockActivity);

    const result = await activityService.recordAchievement(
      1,
      "TestPlayer",
      undefined,
      "ach1",
      "First Win",
      "🏆"
    );

    expect(result).toEqual(mockActivity);
  });

  it("recordTournamentWin should return success", async () => {
    const mockActivity = {
      id: 1,
      type: "tournament" as const,
      playerId: 1,
      playerName: "TestPlayer",
      tournamentId: "tourn1",
      tournamentName: "Weekly Tournament",
      placement: 1,
      prizeAmount: 10000,
      timestamp: new Date(),
    };

    vi.mocked(activityService.recordTournamentWin).mockResolvedValue(mockActivity);

    const result = await activityService.recordTournamentWin(
      1,
      "TestPlayer",
      undefined,
      "tourn1",
      "Weekly Tournament",
      1,
      10000
    );

    expect(result).toEqual(mockActivity);
  });

  it("recordMilestone should return success", async () => {
    const mockActivity = {
      id: 1,
      type: "milestone" as const,
      playerId: 1,
      playerName: "TestPlayer",
      milestoneName: "100 Spins",
      milestoneIcon: "⭐",
      description: "Completed 100 spins",
      timestamp: new Date(),
    };

    vi.mocked(activityService.recordMilestone).mockResolvedValue(mockActivity);

    const result = await activityService.recordMilestone(
      1,
      "TestPlayer",
      undefined,
      "100 Spins",
      "⭐",
      "Completed 100 spins"
    );

    expect(result).toEqual(mockActivity);
  });
});
