import { describe, it, expect, vi } from 'vitest';
import { SponsorshipViewModel } from './SponsorshipViewModel';

describe('SponsorshipViewModel', () => {
  const baseData = {
    id: 'sp-1',
    type: 'leagues' as const,
    entityId: 'league-1',
    entityName: 'Pro League',
    tier: 'main' as const,
    status: 'active' as const,
    applicationDate: '2025-01-01T00:00:00Z',
    approvalDate: '2025-01-02T00:00:00Z',
    startDate: '2025-01-10T00:00:00Z',
    endDate: '2025-02-10T00:00:00Z',
    price: 5_000,
    impressions: 50_000,
    impressionsChange: 10,
    engagement: 3.5,
    details: 'Full season branding',
    entityOwner: 'League Owner',
    applicationMessage: 'Excited to sponsor',
  };

  it('maps core fields and converts dates', () => {
    const vm = new SponsorshipViewModel(baseData);

    expect(vm.id).toBe(baseData.id);
    expect(vm.type).toBe(baseData.type);
    expect(vm.entityId).toBe(baseData.entityId);
    expect(vm.entityName).toBe(baseData.entityName);
    expect(vm.tier).toBe(baseData.tier);
    expect(vm.status).toBe(baseData.status);

    expect(vm.applicationDate).toBeInstanceOf(Date);
    expect(vm.approvalDate).toBeInstanceOf(Date);
    expect(vm.startDate).toBeInstanceOf(Date);
    expect(vm.endDate).toBeInstanceOf(Date);

    expect(vm.price).toBe(baseData.price);
    expect(vm.impressions).toBe(baseData.impressions);
    expect(vm.impressionsChange).toBe(baseData.impressionsChange);
    expect(vm.engagement).toBe(baseData.engagement);
    expect(vm.details).toBe(baseData.details);
    expect(vm.entityOwner).toBe(baseData.entityOwner);
    expect(vm.applicationMessage).toBe(baseData.applicationMessage);
  });

  it('exposes formatted impressions and price', () => {
    const vm = new SponsorshipViewModel(baseData);

    expect(vm.formattedImpressions).toBe(baseData.impressions.toLocaleString());
    expect(vm.formattedPrice).toBe(`$${baseData.price}`);
  });

  it('computes daysRemaining and expiringSoon based on endDate', () => {
    const now = new Date('2025-01-01T00:00:00Z');
    vi.setSystemTime(now);

    const vm = new SponsorshipViewModel({
      ...baseData,
      endDate: '2025-01-15T00:00:00Z',
    });

    expect(vm.daysRemaining).toBeGreaterThan(0);
    expect(vm.isExpiringSoon).toBe(true);

    const farFuture = new SponsorshipViewModel({
      ...baseData,
      endDate: '2025-12-31T00:00:00Z',
    });
    expect(farFuture.isExpiringSoon).toBe(false);

    const past = new SponsorshipViewModel({
      ...baseData,
      endDate: '2024-12-31T00:00:00Z',
    });
    expect(past.daysRemaining).toBeLessThanOrEqual(0);
    expect(past.isExpiringSoon).toBe(false);

    vi.useRealTimers();
  });

  it('derives human-readable status and type labels', () => {
    const active = new SponsorshipViewModel({ ...baseData, status: 'active' });
    const pending = new SponsorshipViewModel({ ...baseData, status: 'pending_approval' });
    const approved = new SponsorshipViewModel({ ...baseData, status: 'approved' });
    const rejected = new SponsorshipViewModel({ ...baseData, status: 'rejected' });
    const expired = new SponsorshipViewModel({ ...baseData, status: 'expired' });

    expect(active.statusLabel).toBe('Active');
    expect(pending.statusLabel).toBe('Awaiting Approval');
    expect(approved.statusLabel).toBe('Approved');
    expect(rejected.statusLabel).toBe('Declined');
    expect(expired.statusLabel).toBe('Expired');

    const league = new SponsorshipViewModel({ ...baseData, type: 'leagues' });
    const team = new SponsorshipViewModel({ ...baseData, type: 'teams' });
    const driver = new SponsorshipViewModel({ ...baseData, type: 'drivers' });
    const race = new SponsorshipViewModel({ ...baseData, type: 'races' });
    const platform = new SponsorshipViewModel({ ...baseData, type: 'platform' });

    expect(league.typeLabel).toBe('League');
    expect(team.typeLabel).toBe('Team');
    expect(driver.typeLabel).toBe('Driver');
    expect(race.typeLabel).toBe('Race');
    expect(platform.typeLabel).toBe('Platform');
  });

  it('formats sponsorship period as month-year range', () => {
    const vm = new SponsorshipViewModel({
      ...baseData,
      startDate: '2025-01-10T00:00:00Z',
      endDate: '2025-03-10T00:00:00Z',
    });

    const [start, end] = vm.periodDisplay.split(' - ');
    expect(typeof start).toBe('string');
    expect(typeof end).toBe('string');
    expect(start.length).toBeGreaterThan(0);
    expect(end.length).toBeGreaterThan(0);
  });
});
