import { render, fireEvent, screen } from '@testing-library/svelte';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import ActionListbox from './ActionListbox.svelte';
beforeEach(() => {
    HTMLElement.prototype.showPopover = vi.fn();
    HTMLElement.prototype.hidePopover = vi.fn();
    Object.defineProperty(global, 'crypto', {
        value: {
            randomUUID: () => '123-test-id',
        },
    });
});
describe('ActionListbox Component', () => {
    it('should render the title when provided', () => {
        const title = 'Menu Options';
        render(ActionListbox, { title });
        expect(screen.getByText(title)).toBeTruthy();
        expect(screen.getByRole('heading', { level: 3 }).classList.contains('mc-listbox__title')).toBeTruthy();
    });
    it('should not render the title if not provided', () => {
        const { container } = render(ActionListbox);
        const titleElement = container.querySelector('.mc-listbox__title');
        expect(titleElement).toBeNull();
    });
    describe('Positioning Classes', () => {
        it('should apply the default position class (bottom)', () => {
            const { container } = render(ActionListbox);
            const mainDiv = container.querySelector('.mc-listbox');
            expect(mainDiv?.classList.contains('mc-listbox--bottom')).toBeTruthy();
        });
        it('should apply correct classes based on position prop', () => {
            const { container } = render(ActionListbox, { position: 'left' });
            const mainDiv = container.querySelector('.mc-listbox');
            expect(mainDiv?.classList.contains('mc-listbox--left')).toBeTruthy();
        });
        it('should handle single position value', () => {
            const { container } = render(ActionListbox, { position: 'top' });
            const mainDiv = container.querySelector('.mc-listbox');
            expect(mainDiv?.classList.contains('mc-listbox--top')).toBeTruthy();
        });
    });
    describe('Events and Callbacks', () => {
        it('should call onclose prop and dispatch close event when clicking the close button', async () => {
            const onclose = vi.fn();
            const { container } = render(ActionListbox, { onclose });
            const closeEventSpy = vi.fn();
            const element = container.querySelector('.mc-listbox');
            element?.addEventListener('close', closeEventSpy);
            const closeButton = screen.getByLabelText('Close');
            await fireEvent.click(closeButton);
            expect(onclose).toHaveBeenCalledTimes(1);
            expect(closeEventSpy).toHaveBeenCalled();
        });
    });
    describe('Open state logic', () => {
        it('should set the popover attributes correctly', () => {
            const { container } = render(ActionListbox);
            const popoverContent = container.querySelector('.mc-listbox__content');
            expect(popoverContent?.hasAttribute('popover')).toBe(false);
        });
        it('should reflect the open state if possible', async () => {
            const { component } = render(ActionListbox, { open: true });
            expect(component.open).toBe(true);
        });
        it('should close when clicking outside the component', async () => {
            const { component } = render(ActionListbox, { open: true });
            await fireEvent.mouseDown(document.body);
            expect(component.open).toBe(false);
        });
        it('should NOT close when clicking inside the component', async () => {
            const { component, container } = render(ActionListbox, { open: true });
            const innerDiv = container.querySelector('.mc-listbox__content');
            await fireEvent.mouseDown(innerDiv);
            expect(component.open).toBe(true);
        });
    });
});
