import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DevIndexOverlay from '../../resources/js/components/DevIndexOverlay.vue';
import { useDevIndices } from '../../resources/js/composables/useDevIndices';

describe('DevIndexOverlay', () => {
    beforeEach(() => useDevIndices().reset());

    it('hidden when no current target', () => {
        mount(DevIndexOverlay, { attachTo: document.body });
        expect(document.querySelector('.dx-badge')).toBeNull();
    });

    it('shows badge with id + tag when target is set', async () => {
        const el = document.createElement('button');
        el.setAttribute('data-dx', '1030');
        el.textContent = 'Создать';
        document.body.appendChild(el);

        const dx = useDevIndices();
        dx.setTarget(el);

        mount(DevIndexOverlay, { attachTo: document.body });
        await nextTick();
        const badge = document.querySelector('.dx-badge');
        expect(badge).not.toBeNull();
        expect(badge!.textContent).toContain('1030');
        expect(badge!.textContent!.toLowerCase()).toContain('button');

        document.body.removeChild(el);
    });

    it('Esc clears the target', async () => {
        const el = document.createElement('div');
        el.setAttribute('data-dx', '5');
        document.body.appendChild(el);
        const dx = useDevIndices();
        dx.setTarget(el);

        mount(DevIndexOverlay, { attachTo: document.body });
        await nextTick();

        document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }));
        await nextTick();

        expect(dx.currentId.value).toBeNull();
        document.body.removeChild(el);
    });

    it('clicking the badge copies "#<id>" to clipboard', async () => {
        const writeText = vi.fn().mockResolvedValue(undefined);
        Object.defineProperty(navigator, 'clipboard', {
            value: { writeText },
            configurable: true,
        });

        const el = document.createElement('button');
        el.setAttribute('data-dx', '1030');
        document.body.appendChild(el);
        useDevIndices().setTarget(el);

        mount(DevIndexOverlay, { attachTo: document.body });
        await nextTick();

        const badge = document.querySelector('.dx-badge') as HTMLElement;
        expect(badge).not.toBeNull();
        badge.click();
        await nextTick();
        expect(writeText).toHaveBeenCalledWith('#1030');

        document.body.removeChild(el);
    });
});

describe('DevIndexOverlay — Alt-keys + overlay-mode', () => {
    beforeEach(() => useDevIndices().reset());

    it('Alt+ArrowUp walks to parent', async () => {
        const grand = document.createElement('div');
        grand.setAttribute('data-dx', '100');
        const child = document.createElement('button');
        child.setAttribute('data-dx', '200');
        grand.appendChild(child);
        document.body.appendChild(grand);

        const dx = useDevIndices();
        dx.setTarget(child);

        mount(DevIndexOverlay, { attachTo: document.body });
        await nextTick();

        document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp', altKey: true }));
        await nextTick();

        expect(dx.currentId.value).toBe(100);
        document.body.removeChild(grand);
    });

    it('Alt+ArrowDown walks to first descendant', async () => {
        const parent = document.createElement('div');
        parent.setAttribute('data-dx', '1');
        const child = document.createElement('span');
        child.setAttribute('data-dx', '2');
        parent.appendChild(child);
        document.body.appendChild(parent);

        const dx = useDevIndices();
        dx.setTarget(parent);

        mount(DevIndexOverlay, { attachTo: document.body });
        await nextTick();

        document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', altKey: true }));
        await nextTick();

        expect(dx.currentId.value).toBe(2);
        document.body.removeChild(parent);
    });

    it('Alt+Shift+I toggles overlay-mode', async () => {
        mount(DevIndexOverlay, { attachTo: document.body });
        await nextTick();

        const dx = useDevIndices();
        expect(dx.overlayMode.value).toBe(false);

        document.dispatchEvent(new KeyboardEvent('keydown', { key: 'I', altKey: true, shiftKey: true }));
        await nextTick();
        expect(dx.overlayMode.value).toBe(true);

        document.dispatchEvent(new KeyboardEvent('keydown', { key: 'I', altKey: true, shiftKey: true }));
        await nextTick();
        expect(dx.overlayMode.value).toBe(false);
    });

    it('overlay-mode renders mini-badges on all [data-dx] elements', async () => {
        const a = document.createElement('div');
        a.setAttribute('data-dx', '1');
        const b = document.createElement('div');
        b.setAttribute('data-dx', '2');
        document.body.append(a, b);

        mount(DevIndexOverlay, { attachTo: document.body });
        useDevIndices().toggleOverlay();
        await nextTick();

        const minis = document.querySelectorAll('.dx-mini');
        expect(minis.length).toBeGreaterThanOrEqual(2);

        document.body.removeChild(a);
        document.body.removeChild(b);
    });
});
