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

import { createElementTest, BaseTestConfig } from '../../tests/test-framework'
import './datepicker-popup'
import '../calendar/calendar'

import { PktDatepickerPopup } from './datepicker-popup'
import { PktCalendar } from '../calendar/calendar'

export interface IDatepickerPopupTest extends BaseTestConfig {
  open?: boolean
}

const createPopupTest = async (config: IDatepickerPopupTest = {}) => {
  const { container, element } = await createElementTest('pkt-datepicker-popup' as any, config)
  return { container, popup: element as PktDatepickerPopup }
}

afterEach(() => {
  document.body.innerHTML = ''
})

describe('PktDatepickerPopup', () => {
  test('opens when show() is called', async () => {
    const { popup } = await createPopupTest()
    await popup.updateComplete

    popup.show()
    await popup.updateComplete
    expect(popup.open).toBe(true)
  })

  test('closes when clicking outside', async () => {
    const { popup } = await createPopupTest()
    await popup.updateComplete

    popup.show()
    await popup.updateComplete
    expect(popup.open).toBe(true)

    fireEvent.click(document.body)
    await popup.updateComplete
    expect(popup.open).toBe(false)
  })

  test('closes on Escape key', async () => {
    const { popup } = await createPopupTest()
    await popup.updateComplete

    popup.show()
    await popup.updateComplete
    expect(popup.open).toBe(true)

    fireEvent.keyDown(popup, { key: 'Escape' })
    await popup.updateComplete
    expect(popup.open).toBe(false)
  })

  test('re-dispatches date-selected from child calendar', async () => {
    const { popup } = await createPopupTest({ open: true })
    await popup.updateComplete

    const handler = vi.fn()
    popup.addEventListener('date-selected', (e: any) => handler(e))

    const cal = popup.querySelector('pkt-calendar') as PktCalendar | null
    expect(cal).toBeTruthy()
    const detail = ['2025-09-17']
    cal?.dispatchEvent(new CustomEvent('date-selected', { detail, bubbles: true, composed: true }))

    expect(handler).toHaveBeenCalled()
    const eventArg = handler.mock.calls[0][0]
    expect(eventArg.detail).toEqual(detail)
  })
})
