import { test, expect } from '@playwright/test';

test('List fixtures cover normal, grouped, tree and virtual modes', async ({ page }) => {
    await page.goto('/test/list_test.html');

    await expect(page.locator('#listStd .list-group-item').first()).toBeVisible();
    await expect(page.locator('#listGrp .list-group-item').first()).toBeVisible();
    await expect(page.locator('#listTree .list-group-item').first()).toBeVisible();
    await expect(page.locator('#listFast .list-group-item').first()).toBeVisible();

    const treeBefore = await page.locator('#listTree .list-group-item').count();
    await page.locator('#listTree .bi-caret-down-fill').first().click();
    await page.waitForTimeout(100);
    const treeAfter = await page.locator('#listTree .list-group-item').count();
    expect(treeAfter).toBeLessThan(treeBefore);

    const fastInfo = await page.locator('#listFast').evaluate(async node => {
        const visibleText = () => Array.from(node.querySelectorAll('.list-group-item .fw-bold')).map(el => el.textContent.trim());
        const initial = visibleText();
        node.scrollTop = node.scrollHeight;
        node.dispatchEvent(new Event('scroll'));
        await new Promise(resolve => setTimeout(resolve, 300));
        const final = visibleText();
        return {
            count: node.querySelectorAll('.list-group-item').length,
            scrollTop: node.scrollTop,
            initialFirst: initial[0],
            finalFirst: final[0],
            finalLast: final[final.length - 1]
        };
    });

    expect(fastInfo.count).toBeGreaterThan(0);
    expect(fastInfo.count).toBeLessThan(400);
    expect(fastInfo.scrollTop).toBeGreaterThan(0);
    expect(fastInfo.initialFirst).not.toBe(fastInfo.finalFirst);
    expect(fastInfo.finalLast).toContain('Virtual Item');
});

test('List component supports internal filtering and sorting', async ({ page }) => {
    page.on('console', msg => console.log('BROWSER CONSOLE:', msg.text()));
    await page.goto('/test/list_test.html');

    // 1. Test Standard List Filtering
    await page.fill('#searchInput', 'Item 5');
    await page.waitForTimeout(100);
    const itemsText = await page.locator('#listStd .list-group-item').allTextContents();
    // Item 5, Item 50 should be there, but not Item 1, 2, etc.
    expect(itemsText.every(text => text.includes('Item 5'))).toBe(true);
    expect(itemsText.length).toBe(2); // Item 5 and Item 50

    // Clear filter
    await page.fill('#searchInput', '');
    await page.waitForTimeout(100);

    // 2. Test Standard List Sorting
    // Default is: Item 1, Item 2...
    await page.selectOption('#sortSelect', '-label');
    await page.waitForTimeout(100);
    const sortedText = await page.locator('#listStd .list-group-item').first().textContent();
    expect(sortedText.trim()).toContain('Item 9'); // Lexicographically descending

    // 3. Test Group List Filtering
    await page.fill('#grpSearchInput', 'Member 3');
    await page.waitForTimeout(100);
    // Since grpItems have label 'Member X' and group fields. Only member matching '3' or '30' or '31' etc. will show.
    const grpItemsCount = await page.locator('#listGrp .list-group-item').count();
    // Should be filtered down considerably
    expect(grpItemsCount).toBeLessThan(40);

    // 4. Test Tree List Filtering (Crucial check for ancestry propagation)
    await page.fill('#treeSearchInput', 'UI Team');
    await page.waitForTimeout(100);
    
    // UI Team should be visible
    const uiTeam = page.locator('#listTree .list-group-item', { hasText: 'UI Team' });
    await expect(uiTeam).toBeVisible();

    // Ancestor "Company HQ" and "R&D Division" must also be visible
    const parent1 = page.locator('#listTree .list-group-item', { hasText: 'Company HQ' });
    const parent2 = page.locator('#listTree .list-group-item', { hasText: 'R&D Division' });
    await expect(parent1).toBeVisible();
    await expect(parent2).toBeVisible();

    // Sibling node "Operations" or "Cloud Ops" should NOT be visible
    const sibling1 = page.locator('#listTree .list-group-item', { hasText: 'Operations' });
    const sibling2 = page.locator('#listTree .list-group-item', { hasText: 'Cloud Ops' });
    await expect(sibling1).not.toBeVisible();
    await expect(sibling2).not.toBeVisible();
});

