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

const pageTagsApi = vi.hoisted(() => ({
    listMyPageTags: vi.fn()
}));

vi.mock('$lib/api/page_tags', async () => {
    const actual =
        await vi.importActual<typeof import('$lib/api/page_tags')>(
            '$lib/api/page_tags'
        );
    return { ...actual, ...pageTagsApi };
});

afterEach(() => {
    cleanup();
    vi.clearAllMocks();
});

function tagged(extra: Record<string, unknown> = {}) {
    return {
        tag: 'funny',
        page_id: 'p1',
        chapter_id: 'ch1',
        manga_id: 'm1',
        page_number: 1,
        chapter_number: 1,
        chapter_title: null,
        manga_title: 'Berserk',
        storage_key: 'mangas/m1/chapters/ch1/pages/0001.png',
        tagged_at: '2026-01-01T00:00:00Z',
        ...extra
    };
}

describe('PageTagsList', () => {
    it('renders empty state when nothing is tagged', () => {
        render(PageTagsList, {
            props: { initialItems: [], initialDistinct: [] }
        });
        expect(screen.getByTestId('library-page-tags-empty')).toBeTruthy();
    });

    it('renders chip cloud and list from initial props', () => {
        render(PageTagsList, {
            props: {
                initialItems: [tagged({ tag: 'funny' })],
                initialDistinct: [
                    { tag: 'funny', count: 5 },
                    { tag: 'fight', count: 2 }
                ]
            }
        });
        expect(screen.getByTestId('library-page-tags-chip-funny')).toBeTruthy();
        expect(screen.getByTestId('library-page-tags-chip-fight')).toBeTruthy();
        expect(screen.getByTestId('library-page-tags-list')).toBeTruthy();
    });

    it('clicking a chip filters via listMyPageTags', async () => {
        pageTagsApi.listMyPageTags.mockResolvedValueOnce({
            items: [tagged({ tag: 'fight' })],
            page: { limit: 100, offset: 0, total: 1 }
        });
        render(PageTagsList, {
            props: {
                initialItems: [tagged({ tag: 'funny' })],
                initialDistinct: [
                    { tag: 'funny', count: 5 },
                    { tag: 'fight', count: 2 }
                ]
            }
        });
        await fireEvent.click(screen.getByTestId('library-page-tags-chip-fight'));
        await tick();
        await Promise.resolve();
        await tick();
        expect(pageTagsApi.listMyPageTags).toHaveBeenCalledWith({
            tag: 'fight',
            limit: 100
        });
    });
});
