import { describe, it, expect, beforeEach, vi } from "vitest";
import { vipPerksRouter } from "./vipPerks.ts";
import * as vipPerksService from "../services/vipPerksService.ts";

// Mock the VIP perks service
vi.mock("../services/vipPerksService", () => ({
  getPlayerVIPStatus: vi.fn(),
  updatePlayerSpend: vi.fn(),
  addCashback: vi.fn(),
  claimMonthlyBonus: vi.fn(),
  claimBirthdayBonus: vi.fn(),
  getVIPTierInfo: vi.fn(),
  getAllVIPTiers: vi.fn(),
  getExclusiveGames: vi.fn(),
  getVIPStats: vi.fn(),
}));

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

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

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

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

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

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

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

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

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

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

  it("getPlayerVIPStatus should return player VIP status", async () => {
    const mockStatus = {
      playerId: 1,
      currentTier: "bronze" as const,
      totalSpent: 0,
      progressToNextTier: 0,
      nextTierName: "Silver VIP",
      nextTierMinSpend: 10000,
      perksUnlocked: [],
      cashbackEarned: 0,
      monthlyBonusEarned: 0,
    };

    vi.mocked(vipPerksService.getPlayerVIPStatus).mockResolvedValue(mockStatus);

    const result = await vipPerksService.getPlayerVIPStatus(1);
    expect(result).toEqual(mockStatus);
    expect(vipPerksService.getPlayerVIPStatus).toHaveBeenCalledWith(1);
  });

  it("updatePlayerSpend should return new tier", async () => {
    vi.mocked(vipPerksService.updatePlayerSpend).mockResolvedValue("silver");

    const result = await vipPerksService.updatePlayerSpend(1, 10000);
    expect(result).toBe("silver");
    expect(vipPerksService.updatePlayerSpend).toHaveBeenCalledWith(1, 10000);
  });

  it("addCashback should return cashback amount", async () => {
    vi.mocked(vipPerksService.addCashback).mockResolvedValue(100);

    const result = await vipPerksService.addCashback(1, 10000);
    expect(result).toBe(100);
    expect(vipPerksService.addCashback).toHaveBeenCalledWith(1, 10000);
  });

  it("claimMonthlyBonus should return bonus amount", async () => {
    vi.mocked(vipPerksService.claimMonthlyBonus).mockResolvedValue(500);

    const result = await vipPerksService.claimMonthlyBonus(1);
    expect(result).toBe(500);
    expect(vipPerksService.claimMonthlyBonus).toHaveBeenCalledWith(1);
  });

  it("claimBirthdayBonus should return bonus amount", async () => {
    vi.mocked(vipPerksService.claimBirthdayBonus).mockResolvedValue(1000);

    const result = await vipPerksService.claimBirthdayBonus(1);
    expect(result).toBe(1000);
    expect(vipPerksService.claimBirthdayBonus).toHaveBeenCalledWith(1);
  });

  it("getVIPTierInfo should return tier info", async () => {
    const mockTierInfo = {
      tier: "bronze" as const,
      displayName: "Bronze VIP",
      color: "#CD7F32",
      icon: "🥉",
      minSpend: 0,
      perks: [],
      cashbackRate: 1,
      bonusMultiplier: 1,
      exclusiveGames: [],
      prioritySupport: false,
      monthlyBonus: 500,
      birthdayBonus: 1000,
    };

    vi.mocked(vipPerksService.getVIPTierInfo).mockResolvedValue(mockTierInfo);

    const result = await vipPerksService.getVIPTierInfo("bronze");
    expect(result).toEqual(mockTierInfo);
    expect(vipPerksService.getVIPTierInfo).toHaveBeenCalledWith("bronze");
  });

  it("getAllVIPTiers should return all tiers", async () => {
    const mockTiers = [
      {
        tier: "bronze" as const,
        displayName: "Bronze VIP",
        color: "#CD7F32",
        icon: "🥉",
        minSpend: 0,
        perks: [],
        cashbackRate: 1,
        bonusMultiplier: 1,
        exclusiveGames: [],
        prioritySupport: false,
        monthlyBonus: 500,
        birthdayBonus: 1000,
      },
    ];

    vi.mocked(vipPerksService.getAllVIPTiers).mockResolvedValue(mockTiers);

    const result = await vipPerksService.getAllVIPTiers();
    expect(result.length).toBeGreaterThan(0);
    expect(vipPerksService.getAllVIPTiers).toHaveBeenCalled();
  });

  it("getExclusiveGames should return exclusive games", async () => {
    const mockGames = ["game1", "game2", "game3"];

    vi.mocked(vipPerksService.getExclusiveGames).mockResolvedValue(mockGames);

    const result = await vipPerksService.getExclusiveGames(1);
    expect(result).toEqual(mockGames);
    expect(vipPerksService.getExclusiveGames).toHaveBeenCalledWith(1);
  });

  it("getVIPStats should return VIP statistics", async () => {
    const mockStats = {
      totalVIPPlayers: 100,
      byTier: {
        bronze: 50,
        silver: 30,
        gold: 15,
        platinum: 3,
        diamond: 1,
        elite: 1,
      },
      totalCashbackDistributed: 50000,
      totalBonusesDistributed: 100000,
    };

    vi.mocked(vipPerksService.getVIPStats).mockResolvedValue(mockStats);

    const result = await vipPerksService.getVIPStats();
    expect(result).toEqual(mockStats);
    expect(vipPerksService.getVIPStats).toHaveBeenCalled();
  });
});
