import { describe, expect, it } from 'vitest'
import {
  calendarGridDays,
  daysBetween,
  eventsForCalendarDay,
  isSameDay,
  parseDateStr,
  selectedBlockRange,
  toDateStr,
  type CalendarEvent,
} from './VehicleCalendar'

describe('VehicleCalendar helpers', () => {
  it('formats and parses local date-only strings without shifting the calendar day', () => {
    const parsed = parseDateStr('2026-02-09')

    expect(parsed.getFullYear()).toBe(2026)
    expect(parsed.getMonth()).toBe(1)
    expect(parsed.getDate()).toBe(9)
    expect(toDateStr(parsed)).toBe('2026-02-09')
  })

  it('builds a full week-aligned month grid with leading and trailing blanks', () => {
    const grid = calendarGridDays(2026, 2)

    expect(grid).toHaveLength(28)
    expect(grid[0]?.getDate()).toBe(1)
    expect(grid.at(-1)?.getDate()).toBe(28)

    const march = calendarGridDays(2026, 3)
    expect(march).toHaveLength(35)
    expect(march[0]?.getDate()).toBe(1)
    expect(march[6]?.getDate()).toBe(7)
    expect(march.at(-1)).toBeNull()
  })

  it('treats reservation end dates as exclusive when mapping events to days', () => {
    const events: CalendarEvent[] = [
      { id: 'r1', type: 'RESERVATION', startDate: '2026-06-10T10:00:00.000Z', endDate: '2026-06-13T10:00:00.000Z', status: 'CONFIRMED', label: 'Reservation' },
      { id: 'b1', type: 'BLOCK', startDate: '2026-06-13T00:00:00.000Z', endDate: '2026-06-14T00:00:00.000Z', status: null, label: 'Block' },
    ]

    expect(eventsForCalendarDay(events, parseDateStr('2026-06-10')).map((event) => event.id)).toEqual(['r1'])
    expect(eventsForCalendarDay(events, parseDateStr('2026-06-12')).map((event) => event.id)).toEqual(['r1'])
    expect(eventsForCalendarDay(events, parseDateStr('2026-06-13')).map((event) => event.id)).toEqual(['b1'])
  })

  it('normalizes two clicked days into an inclusive visual range with exclusive end date', () => {
    expect(selectedBlockRange('2026-06-12', parseDateStr('2026-06-10'))).toEqual({
      startDate: '2026-06-10',
      endDate: '2026-06-13',
    })
    expect(selectedBlockRange('2026-06-10', parseDateStr('2026-06-12'))).toEqual({
      startDate: '2026-06-10',
      endDate: '2026-06-13',
    })
  })

  it('compares calendar days and calculates day spans independent of clock time', () => {
    expect(isSameDay(new Date(2026, 5, 9, 1), new Date(2026, 5, 9, 23))).toBe(true)
    expect(isSameDay(new Date(2026, 5, 9), new Date(2026, 5, 10))).toBe(false)
    expect(daysBetween(parseDateStr('2026-06-09'), parseDateStr('2026-06-12'))).toBe(3)
  })
})
