import { describe, it, expect } from 'vitest'
import { describeRecurrence } from './recurrenceDescription'

// All test dates fall inside EU DST (Mar 29 – Oct 25, 2026), so Berlin is UTC+2.
// We spell the UTC instant explicitly so tests are timezone-independent.
const tuesdayFirstOfMonth = '2026-04-07T16:30:00.000Z' // Tue 2026-04-07 18:30 Berlin
const monday2ndOfMonth = '2026-04-13T16:30:00.000Z' // Mon 2026-04-13 18:30 Berlin
const sunday13thOfMonth = '2026-09-13T08:00:00.000Z' // Sun 2026-09-13 10:00 Berlin
const monday5thOfMonth = '2026-03-30T18:00:00.000Z' // Mon 2026-03-30 20:00 Berlin

describe('describeRecurrence', () => {
  it('returns undefined for none / missing recurrenceType', () => {
    expect(describeRecurrence({ recurrenceType: 'none', date: monday2ndOfMonth })).toBeUndefined()
    expect(describeRecurrence({ recurrenceType: null, date: monday2ndOfMonth } as never)).toBeUndefined()
  })

  it('describes daily with time from event.date', () => {
    const dateAt10 = '2026-04-13T08:00:00.000Z' // 10:00 Berlin
    expect(describeRecurrence({ recurrenceType: 'daily', date: dateAt10 })).toBe(
      'Täglich um 10:00 Uhr',
    )
  })

  it('describes weekly using the weekday and time of event.date', () => {
    expect(describeRecurrence({ recurrenceType: 'weekly', date: tuesdayFirstOfMonth })).toBe(
      'Jeden Dienstag um 18:30 Uhr',
    )
  })

  it('describes biweekly', () => {
    expect(describeRecurrence({ recurrenceType: 'biweekly', date: monday2ndOfMonth })).toBe(
      'Alle 2 Wochen, Montag um 18:30 Uhr',
    )
  })

  it('describes monthlyByDate using the day-of-month from event.date', () => {
    expect(describeRecurrence({ recurrenceType: 'monthlyByDate', date: sunday13thOfMonth })).toBe(
      'Monatlich am 13. um 10:00 Uhr',
    )
  })

  it('describes monthlyByWeekday using the Nth weekday from event.date', () => {
    expect(describeRecurrence({ recurrenceType: 'monthlyByWeekday', date: monday2ndOfMonth })).toBe(
      'Monatlich am 2. Montag um 18:30 Uhr',
    )
    expect(describeRecurrence({ recurrenceType: 'monthlyByWeekday', date: tuesdayFirstOfMonth })).toBe(
      'Monatlich am 1. Dienstag um 18:30 Uhr',
    )
  })

  it('clamps a 5th-occurrence weekday to the 4th (matches generator)', () => {
    expect(describeRecurrence({ recurrenceType: 'monthlyByWeekday', date: monday5thOfMonth })).toBe(
      'Monatlich am 4. Montag um 20:00 Uhr',
    )
  })

  it('joins multiple custom rules and appends time once', () => {
    const desc = describeRecurrence({
      recurrenceType: 'custom',
      date: monday2ndOfMonth,
      recurrenceRules: [
        { frequency: 'monthlyByWeekday', weekday: 'tuesday', weekOfMonth: 'third' },
        { frequency: 'monthlyByWeekday', weekday: 'thursday', weekOfMonth: 'fourth' },
      ],
    })
    expect(desc).toBe(
      'Am 3. Dienstag jedes Monats · Am 4. Donnerstag jedes Monats um 18:30 Uhr',
    )
  })

  it('skips incomplete custom rules and returns Benutzerdefiniert if none are valid', () => {
    expect(
      describeRecurrence({
        recurrenceType: 'custom',
        date: monday2ndOfMonth,
        recurrenceRules: [
          // missing weekOfMonth
          { frequency: 'monthlyByWeekday', weekday: 'tuesday' },
        ],
      }),
    ).toBe('Benutzerdefiniert um 18:30 Uhr')
  })

  it('omits the time clause when event.date is missing', () => {
    expect(describeRecurrence({ recurrenceType: 'daily', date: null } as never)).toBe('Täglich')
  })

  it('pads minutes correctly (08:05, not 8:5)', () => {
    const dateEarly = '2026-04-13T06:05:00.000Z' // 08:05 Berlin
    expect(describeRecurrence({ recurrenceType: 'daily', date: dateEarly })).toBe(
      'Täglich um 08:05 Uhr',
    )
  })
})
