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

describe('MonthlyRecurrencePattern', () => {
  it('should create valid pattern', () => {
    const pattern = MonthlyRecurrencePattern.create(1, 'Mon');
    expect(pattern.ordinal).toBe(1);
    expect(pattern.weekday).toBe('Mon');
  });

  it('should validate ordinal range', () => {
    expect(() => MonthlyRecurrencePattern.create(0 as 1, 'Mon')).toThrow('MonthlyRecurrencePattern ordinal must be between 1 and 4');
    expect(() => MonthlyRecurrencePattern.create(5 as 1, 'Mon')).toThrow('MonthlyRecurrencePattern ordinal must be between 1 and 4');
  });

  it('should validate weekday', () => {
    expect(() => MonthlyRecurrencePattern.create(1, 'Invalid' as 'Mon')).toThrow('MonthlyRecurrencePattern weekday must be a valid weekday');
  });

  it('should get ordinal suffix', () => {
    const first = MonthlyRecurrencePattern.create(1, 'Mon');
    const second = MonthlyRecurrencePattern.create(2, 'Tue');
    const third = MonthlyRecurrencePattern.create(3, 'Wed');
    const fourth = MonthlyRecurrencePattern.create(4, 'Thu');
    expect(first.getOrdinalSuffix()).toBe('1st');
    expect(second.getOrdinalSuffix()).toBe('2nd');
    expect(third.getOrdinalSuffix()).toBe('3rd');
    expect(fourth.getOrdinalSuffix()).toBe('4th');
  });

  it('should get description', () => {
    const pattern = MonthlyRecurrencePattern.create(2, 'Wed');
    expect(pattern.getDescription()).toBe('2nd Wed of the month');
  });

  it('should have props', () => {
    const pattern = MonthlyRecurrencePattern.create(1, 'Mon');
    expect(pattern.props).toEqual({
      ordinal: 1,
      weekday: 'Mon',
    });
  });

  it('equals', () => {
    const pattern1 = MonthlyRecurrencePattern.create(1, 'Mon');
    const pattern2 = MonthlyRecurrencePattern.create(1, 'Mon');
    const pattern3 = MonthlyRecurrencePattern.create(2, 'Mon');
    const pattern4 = MonthlyRecurrencePattern.create(1, 'Tue');
    expect(pattern1.equals(pattern2)).toBe(true);
    expect(pattern1.equals(pattern3)).toBe(false);
    expect(pattern1.equals(pattern4)).toBe(false);
  });
});