import { describe, it, expect } from 'vitest';
import type { Wallet, WalletSegment } from './model';
import { majorAmount, formatAmount, spendableChips, needsWebSpendWarning, directPurchaseNeedsEmail } from './wallet';

function seg(source: string, chips: number, spendable = true): WalletSegment {
  return { source, chips, spendable };
}

function wallet(segments: WalletSegment[]): Wallet {
  return { segments, adsForever: false, adsPaidUntilMs: 0, hints: 0, rewardChips: 0 };
}

describe('money formatting', () => {
  it('scales roubles by 100 and leaves whole-unit currencies as-is', () => {
    expect(majorAmount(14900, 'RUB')).toBe(149);
    expect(majorAmount(20, 'VOTE')).toBe(20);
    expect(majorAmount(25, 'XTR')).toBe(25);
  });

  it('formats roubles with two decimals and whole-unit currencies as integers', () => {
    expect(formatAmount(14900, 'RUB')).toBe('149.00');
    expect(formatAmount(15050, 'RUB')).toBe('150.50');
    expect(formatAmount(20, 'VOTE')).toBe('20');
    expect(formatAmount(25, 'XTR')).toBe('25');
  });
});

describe('spendableChips', () => {
  it('sums only the spendable segments', () => {
    expect(spendableChips(wallet([seg('direct', 100), seg('vk', 50)]))).toBe(150);
    expect(spendableChips(wallet([seg('direct', 100, false), seg('vk', 50, false)]))).toBe(0);
    expect(spendableChips(wallet([seg('direct', 100), seg('vk', 50, false)]))).toBe(100);
  });
});

describe('needsWebSpendWarning', () => {
  it('does not warn when the direct segment alone covers the price', () => {
    expect(needsWebSpendWarning('direct', [seg('direct', 200), seg('vk', 400)], 150)).toBe(false);
  });

  it('warns when the priority draw reaches into a store (vk/tg) segment', () => {
    // direct 120 + vk covers the rest of a 300 price → touches vk
    expect(needsWebSpendWarning('direct', [seg('direct', 120), seg('vk', 400)], 300)).toBe(true);
  });

  it('warns when only a store segment is spendable and it covers the price', () => {
    expect(needsWebSpendWarning('direct', [seg('vk', 400)], 100)).toBe(true);
    expect(needsWebSpendWarning('direct', [seg('telegram', 400)], 100)).toBe(true);
  });

  it('does not warn when the price exceeds all spendable chips (buy is disabled anyway)', () => {
    expect(needsWebSpendWarning('direct', [seg('direct', 120), seg('vk', 100)], 500)).toBe(false);
  });

  it('never warns inside a VK or Telegram context (spend stays in the same store segment)', () => {
    expect(needsWebSpendWarning('vk', [seg('vk', 400)], 100)).toBe(false);
    expect(needsWebSpendWarning('telegram', [seg('telegram', 400)], 100)).toBe(false);
  });

  it('ignores non-spendable segments (a frozen or untrusted wallet never warns)', () => {
    expect(needsWebSpendWarning('direct', [seg('vk', 400, false)], 100)).toBe(false);
  });
});

describe('directPurchaseNeedsEmail', () => {
  it('asks for an email on the direct rail when the account has none', () => {
    expect(directPurchaseNeedsEmail('direct', '')).toBe(true);
  });

  it('stays quiet once the account has a confirmed email', () => {
    expect(directPurchaseNeedsEmail('direct', 'player@example.com')).toBe(false);
  });

  it('never asks inside VK or Telegram, where the store rail carries its own identity', () => {
    expect(directPurchaseNeedsEmail('vk', '')).toBe(false);
    expect(directPurchaseNeedsEmail('telegram', '')).toBe(false);
  });
});
