import { describe, it, expect, vi, afterEach } from 'vitest';
import { render, screen, cleanup, fireEvent } from '@testing-library/svelte';
import PageContextMenu from './PageContextMenu.svelte';

afterEach(() => cleanup());

const baseProps = {
    open: true,
    anchor: { x: 100, y: 100 },
    onClose: () => {},
    onAddToCollection: () => {},
    onAddTag: () => {},
    onSaveImage: () => {},
    onCopyLink: () => {},
    collectionsCount: 0,
    tags: [] as string[]
};

describe('PageContextMenu', () => {
    it('renders all four action items', () => {
        render(PageContextMenu, { props: baseProps });
        expect(screen.getByTestId('page-context-add-to-collection')).toBeTruthy();
        expect(screen.getByTestId('page-context-add-tag')).toBeTruthy();
        expect(screen.getByTestId('page-context-save-image')).toBeTruthy();
        expect(screen.getByTestId('page-context-copy-link')).toBeTruthy();
    });

    it('invokes onSaveImage and onCopyLink when their items are clicked', () => {
        const onSaveImage = vi.fn();
        const onCopyLink = vi.fn();
        render(PageContextMenu, {
            props: { ...baseProps, onSaveImage, onCopyLink }
        });
        screen.getByTestId('page-context-save-image').click();
        screen.getByTestId('page-context-copy-link').click();
        expect(onSaveImage).toHaveBeenCalledOnce();
        expect(onCopyLink).toHaveBeenCalledOnce();
    });

    it('renders empty-state contextual lines when count=0 and tags=[]', () => {
        render(PageContextMenu, { props: baseProps });
        expect(screen.getByTestId('page-context-collections-line').textContent).toBe(
            'Not in any collection'
        );
        expect(screen.getByTestId('page-context-tags-line').textContent).toBe(
            'No tags yet'
        );
    });

    it('renders loading line when collectionsCount is null', () => {
        render(PageContextMenu, {
            props: { ...baseProps, collectionsCount: null }
        });
        expect(screen.getByTestId('page-context-collections-line').textContent).toBe(
            'Loading…'
        );
    });

    it('renders pluralized line when in multiple collections', () => {
        render(PageContextMenu, {
            props: { ...baseProps, collectionsCount: 3 }
        });
        expect(screen.getByTestId('page-context-collections-line').textContent).toBe(
            'In 3 collections'
        );
    });

    it('renders singular line when in one collection', () => {
        render(PageContextMenu, {
            props: { ...baseProps, collectionsCount: 1 }
        });
        expect(screen.getByTestId('page-context-collections-line').textContent).toBe(
            'In 1 collection'
        );
    });

    it('joins tags with commas', () => {
        render(PageContextMenu, {
            props: { ...baseProps, tags: ['funny', 'fight', 'panel-of-the-day'] }
        });
        expect(screen.getByTestId('page-context-tags-line').textContent).toBe(
            'Tagged: funny, fight, panel-of-the-day'
        );
    });

    it('invokes callbacks when items are clicked', () => {
        const onAddToCollection = vi.fn();
        const onAddTag = vi.fn();
        render(PageContextMenu, {
            props: { ...baseProps, onAddToCollection, onAddTag }
        });
        screen.getByTestId('page-context-add-to-collection').click();
        screen.getByTestId('page-context-add-tag').click();
        expect(onAddToCollection).toHaveBeenCalledOnce();
        expect(onAddTag).toHaveBeenCalledOnce();
    });

    it('closes on Escape', async () => {
        const onClose = vi.fn();
        render(PageContextMenu, { props: { ...baseProps, onClose } });
        await fireEvent.keyDown(document, { key: 'Escape' });
        expect(onClose).toHaveBeenCalledOnce();
    });

    it('does not render when closed', () => {
        render(PageContextMenu, { props: { ...baseProps, open: false } });
        expect(screen.queryByTestId('page-context-menu')).toBeNull();
    });
});
