import '@testing-library/jest-dom'
import { fireEvent } from '@testing-library/dom'

import './calendar'
import { PktCalendar } from './calendar'

const waitForCustomElements = async () => {
  await customElements.whenDefined('pkt-calendar')
}

// Helper function to create calendar markup
const createCalendar = async (calendarProps = '') => {
  const container = document.createElement('div')
  container.innerHTML = `
    <pkt-calendar ${calendarProps}></pkt-calendar>
  `
  document.body.appendChild(container)
  await waitForCustomElements()
  return container
}

// Cleanup after each test
afterEach(() => {
  document.body.innerHTML = ''
})

describe('PktCalendar', () => {
  describe('Keyboard navigation', () => {
    test('handles arrow key navigation', async () => {
      const container = await createCalendar()

      const calendar = container.querySelector('pkt-calendar') as PktCalendar
      await calendar.updateComplete

      const firstDate = calendar.querySelector(
        '.pkt-calendar__date:not(.pkt-calendar__date--disabled)',
      ) as HTMLElement
      firstDate?.focus()

      // Test right arrow
      fireEvent.keyDown(firstDate!, { key: 'ArrowRight' })
      await calendar.updateComplete

      // Check that focus moved (implementation dependent)
      expect(document.activeElement).toBeTruthy()
    })

    test('handles enter key for date selection', async () => {
      const container = await createCalendar()

      const calendar = container.querySelector('pkt-calendar') as PktCalendar
      await calendar.updateComplete

      const firstDate = calendar.querySelector(
        '.pkt-calendar__date:not(.pkt-calendar__date--disabled)',
      ) as HTMLElement
      firstDate?.focus()

      fireEvent.keyDown(firstDate!, { key: 'Enter' })
      await calendar.updateComplete

      expect(firstDate).toHaveClass('pkt-calendar__date--selected')
    })

    test('handles escape key', async () => {
      const container = await createCalendar()

      const calendar = container.querySelector('pkt-calendar') as PktCalendar
      await calendar.updateComplete

      fireEvent.keyDown(calendar, { key: 'Escape' })
      await calendar.updateComplete

      // Should trigger close event if inside a datepicker
      expect(calendar).toBeInTheDocument()
    })
  })

  describe('Edge cases and error handling', () => {
    test('handles invalid date formats gracefully', async () => {
      const container = await createCalendar('earliest="invalid-date" latest="also-invalid"')

      const calendar = container.querySelector('pkt-calendar') as PktCalendar
      await calendar.updateComplete

      // Should not crash and render normally
      expect(calendar).toBeInTheDocument()
      const calendarBody = calendar.querySelector('.pkt-calendar__body')
      expect(calendarBody).toBeInTheDocument()
    })

    test('handles empty selected dates array', async () => {
      const container = await createCalendar('selected=""')

      const calendar = container.querySelector('pkt-calendar') as PktCalendar
      await calendar.updateComplete

      expect(calendar.selected).toEqual([])
      const selectedDates = calendar.querySelectorAll('.pkt-calendar__date--selected')
      expect(selectedDates.length).toBe(0)
    })

    test('handles conflicting properties gracefully', async () => {
      // Both multiple and range shouldn't typically be used together
      const container = await createCalendar('multiple range')

      const calendar = container.querySelector('pkt-calendar') as PktCalendar
      await calendar.updateComplete

      expect(calendar.multiple).toBe(true)
      expect(calendar.range).toBe(true)

      // Should still render without errors
      expect(calendar).toBeInTheDocument()
    })

    test('handles very early dates', async () => {
      const container = await createCalendar('currentmonth="1900-01-01"')

      const calendar = container.querySelector('pkt-calendar') as PktCalendar
      await calendar.updateComplete

      expect(calendar).toBeInTheDocument()
      const calendarBody = calendar.querySelector('.pkt-calendar__body')
      expect(calendarBody).toBeInTheDocument()
    })

    test('handles far future dates', async () => {
      const container = await createCalendar('currentmonth="2100-12-31"')

      const calendar = container.querySelector('pkt-calendar') as PktCalendar
      await calendar.updateComplete

      expect(calendar).toBeInTheDocument()
      const calendarBody = calendar.querySelector('.pkt-calendar__body')
      expect(calendarBody).toBeInTheDocument()
    })
  })
})
