/**
 * Prestige-gated exclusive shop item tests (T011c).
 */
import { describe, it, expect, beforeEach } from 'vitest';
import { Person } from '../../../src/models/Person.js';
import { Player } from '../../../src/models/Player.js';
import {
  getStoreItems,
  purchaseItem,
  resetStoreItemsCacheForTests,
} from '../../../src/services/shop/shop_manager.js';

function makePlayer(prestige: number, money: number): Player {
  const character = new Person({
    id: 'char-1',
    firstname: 'Test',
    lastname: 'Player',
    ageYears: 30,
    money,
    prestige,
  });
  return new Player({
    userId: 'user-1',
    character,
    r: [],
    status: 'playing',
    date: '2024-06-15',
    hourOfDay: 10,
    minuteOfHour: 30,
  });
}

describe('shop prestige gating', () => {
  beforeEach(() => {
    resetStoreItemsCacheForTests();
  });

  it('catalog includes prestige-gated exclusive items', () => {
    const exclusives = getStoreItems().filter(i => i.exclusive);
    expect(exclusives.length).toBeGreaterThanOrEqual(3);
    for (const item of exclusives) {
      expect(item.minPrestige).toBeGreaterThan(0);
    }
  });

  it('rejects purchase of an exclusive item below the prestige threshold', () => {
    const item = getStoreItems().find(i => i.id === 'vintage-supercar-collection')!;
    expect(item.minPrestige).toBe(100);

    const player = makePlayer(50, 10_000_000); // plenty of money, too little prestige
    const result = purchaseItem(player, item.id);

    expect(result.success).toBe(false);
    expect(result.message).toMatch(/prestige/i);
    // No money deducted, no item granted.
    expect(player.c.money).toBe(10_000_000);
    expect((player.c.items ?? []).some(i => i.id === item.id)).toBe(false);
  });

  it('allows purchase of an exclusive item at/above the prestige threshold', () => {
    const item = getStoreItems().find(i => i.id === 'vintage-supercar-collection')!;
    const player = makePlayer(100, 10_000_000); // exactly at threshold

    const result = purchaseItem(player, item.id);

    expect(result.success).toBe(true);
    expect(player.c.money).toBe(10_000_000 - item.price);
    expect((player.c.items ?? []).some(i => i.id === item.id)).toBe(true);
    // Buying the prestige item also boosts prestige.
    expect(player.c.prestige).toBe(100 + item.prestigeBoost);
  });

  it('does not gate ordinary (non-exclusive) items', () => {
    const sportsCar = getStoreItems().find(i => i.name === 'Sports Car')!;
    expect(sportsCar.exclusive).toBe(false);

    const player = makePlayer(0, sportsCar.price);
    const result = purchaseItem(player, sportsCar.id);
    expect(result.success).toBe(true);
  });
});
