import { createMessageElement } from '../../public/call/chat/renderer-chat.js';
import { createParticipantTile, getParticipantTile } from '../../public/call/participants/renderer-participant-grid.js';
import { createUserEntryElement } from '../../public/call/renderers/renderer-ui.js';
import { renderOnlineUsers } from '../../public/call/signaling/connect-directory.js';

const formatTimestamp = value => value;
const unsafeText = '<img src=x onerror=alert(1)>Alice';

function mediaState(overrides = {}) {
    return {
        audio: true,
        video: true,
        isSpeaking: false,
        ...overrides
    };
}

describe('safe dynamic rendering', () => {
    afterEach(() => {
        document.body.innerHTML = '';
    });

    test('renders chat text as text, not markup', () => {
        const element = createMessageElement({
            id: 'msg-1',
            type: 'text',
            isSelf: false,
            senderName: unsafeText,
            senderAvatar: '/images/p1.png',
            content: unsafeText,
            timestamp: 'now'
        }, formatTimestamp);

        expect(element.querySelector('.message-text').textContent).toBe(unsafeText);
        expect(element.querySelector('.message-content img')).toBeNull();
        expect(element.querySelector('.message-sender').textContent).toBe(unsafeText);
    });

    test('renders participant names safely and finds ids without selector injection', () => {
        const participantId = 'room"] [data-bad="1';
        const tile = createParticipantTile(participantId, unsafeText);
        const grid = document.createElement('div');
        grid.appendChild(tile);

        expect(tile.querySelector('.absolute.bottom-3 span').textContent).toBe(unsafeText);
        expect(tile.querySelector('.absolute.bottom-3 img')).toBeNull();
        expect(getParticipantTile(grid, participantId)).toBe(tile);
    });

    test('renders user list entries without interpreting user profile fields as HTML', () => {
        const entry = createUserEntryElement({
            role: 'participant',
            id: 'participant-1',
            user: {
                name: unsafeText,
                avatar: '/images/p2.png',
                mediaState: mediaState({ audio: false })
            }
        });

        expect(entry.textContent).toContain(unsafeText);
        expect(entry.querySelectorAll('img')).toHaveLength(1);
    });

    test('renders online users without injecting markup from directory data', () => {
        const onlineUsersList = document.createElement('div');
        const usersContainer = document.createElement('div');
        const onlineUsersSummary = document.createElement('div');

        renderOnlineUsers({
            users: [{
                name: unsafeText,
                userId: unsafeText,
                avatar: '/images/p1.png',
                role: 'participant',
                connectionId: 'room-1'
            }],
            currentUserId: 'other-user',
            onlineUsersList,
            usersContainer,
            onlineUsersSummary
        });

        expect(usersContainer.textContent).toContain(unsafeText);
        expect(usersContainer.querySelector('button')).toBeNull();
        expect(usersContainer.querySelectorAll('img')).toHaveLength(1);
    });
});
