import { describe, it, expect } from 'vitest';
import { SponsorshipPricing } from './SponsorshipPricing';
import { Money } from './Money';

describe('SponsorshipPricing', () => {
  const mainSlot = {
    tier: 'main' as const,
    price: Money.create(100, 'USD'),
    benefits: ['Logo placement'],
    available: true,
    maxSlots: 1,
  };

  const secondarySlot = {
    tier: 'secondary' as const,
    price: Money.create(50, 'USD'),
    benefits: ['Minor placement'],
    available: true,
    maxSlots: 2,
  };

  it('should create sponsorship pricing', () => {
    const pricing = SponsorshipPricing.create({
      mainSlot,
      acceptingApplications: true,
    });
    expect(pricing.mainSlot).toEqual(mainSlot);
    expect(pricing.acceptingApplications).toBe(true);
  });

  it('should create with defaults', () => {
    const pricing = SponsorshipPricing.create();
    expect(pricing.acceptingApplications).toBe(true);
    expect(pricing.mainSlot).toBeUndefined();
  });

  it('should equal same pricings', () => {
    const p1 = SponsorshipPricing.create({ mainSlot, acceptingApplications: true });
    const p2 = SponsorshipPricing.create({ mainSlot, acceptingApplications: true });
    expect(p1.equals(p2)).toBe(true);
  });

  it('should not equal different pricings', () => {
    const p1 = SponsorshipPricing.create({ mainSlot, acceptingApplications: true });
    const p2 = SponsorshipPricing.create({ mainSlot, acceptingApplications: false });
    expect(p1.equals(p2)).toBe(false);
  });

  describe('isSlotAvailable', () => {
    it('should return availability for main slot', () => {
      const pricing = SponsorshipPricing.create({ mainSlot });
      expect(pricing.isSlotAvailable('main')).toBe(true);
    });

    it('should return availability for secondary slot', () => {
      const pricing = SponsorshipPricing.create({ secondarySlots: secondarySlot });
      expect(pricing.isSlotAvailable('secondary')).toBe(true);
    });

    it('should return false for unavailable main slot', () => {
      const unavailableMain = { ...mainSlot, available: false };
      const pricing = SponsorshipPricing.create({ mainSlot: unavailableMain });
      expect(pricing.isSlotAvailable('main')).toBe(false);
    });

    it('should return false for undefined main slot', () => {
      const pricing = SponsorshipPricing.create();
      expect(pricing.isSlotAvailable('main')).toBe(false);
    });
  });

  describe('getPrice', () => {
    it('should return price for main slot', () => {
      const pricing = SponsorshipPricing.create({ mainSlot });
      expect(pricing.getPrice('main')).toEqual(mainSlot.price);
    });

    it('should return null for undefined main slot', () => {
      const pricing = SponsorshipPricing.create();
      expect(pricing.getPrice('main')).toBeNull();
    });
  });

  describe('getBenefits', () => {
    it('should return benefits for main slot', () => {
      const pricing = SponsorshipPricing.create({ mainSlot });
      expect(pricing.getBenefits('main')).toEqual(mainSlot.benefits);
    });

    it('should return empty array for undefined main slot', () => {
      const pricing = SponsorshipPricing.create();
      expect(pricing.getBenefits('main')).toEqual([]);
    });
  });

  describe('updateMainSlot', () => {
    it('should update main slot', () => {
      const pricing = SponsorshipPricing.create();
      const updated = pricing.updateMainSlot({ price: Money.create(200, 'USD') });
      expect(updated.mainSlot?.price).toEqual(Money.create(200, 'USD'));
      expect(updated.mainSlot?.tier).toBe('main');
    });
  });

  describe('updateSecondarySlot', () => {
    it('should update secondary slot', () => {
      const pricing = SponsorshipPricing.create();
      const updated = pricing.updateSecondarySlot({ price: Money.create(75, 'USD') });
      expect(updated.secondarySlots?.price).toEqual(Money.create(75, 'USD'));
      expect(updated.secondarySlots?.tier).toBe('secondary');
    });
  });

  describe('setAcceptingApplications', () => {
    it('should set accepting applications', () => {
      const pricing = SponsorshipPricing.create({ acceptingApplications: true });
      const updated = pricing.setAcceptingApplications(false);
      expect(updated.acceptingApplications).toBe(false);
    });
  });
});