import { render } from "@cerxes/csx";
import { testContainer } from "../utils/test-container";

describe("Key-property tests", () => {
    test("Keyed list", async () => {
        let initialRendered = new Map();
        let initIndexes = [1, 2, 3, 4];
        
        let makeSpec = (targetList, indexes)=>(
            <ul>
                {
                    indexes.map(index => (
                        <li id={`li_${index}`} key={index} ref={(el) => targetList.set(index, el)}>
                            {index}
                        </li>
                    ))
                }
            </ul>
        );
        
        let initialVSpec = makeSpec(initialRendered, initIndexes);
        
        let rendered = render(initialVSpec);
        let container = testContainer(rendered);
        
        expect(container.innerHTML).toBe(
            [
                `<ul>`,
                ...initIndexes.map(index=>`<li id="${`li_${index}`}">${index}</li>`),
                `</ul>`
            ].join('')
        );
        
        expect(initialRendered.size).toBe(4);
        for(let rendered of initialRendered){
            expect(rendered).not.toBeUndefined();
        }
        
        // Reverse order
        let reorderedIndexes = [4,3,2,1];
        let rerenderedIndexes = new Map(initialRendered);
        let updatedVSpec =  makeSpec(rerenderedIndexes, reorderedIndexes);
        render(updatedVSpec, {host: rendered, old: initialVSpec});
    
        // Updated (reverse order)
        expect(container.innerHTML).toBe(
            [
                `<ul>`,
                ...reorderedIndexes.map(index=>`<li id="${`li_${index}`}">${index}</li>`),
                `</ul>`
            ].join('')
        );
    
        // Validate that items were merely re-arranged and not re-created
        expect(rerenderedIndexes.size).toBe(4);
        for(let i of initIndexes){
            let initRendered = initialRendered.get(i);
            let reorderedRendered = rerenderedIndexes.get(i);
            expect(initRendered === reorderedRendered).toBe(true); // These should've remained the same
        }
    
        // Add items and change order
        let additionalIndexes = [0, 1, 2.5, 2, 3, 4, 5.5];
        let additionalRerenderedIndexes = new Map(initialRendered);
        let secondUpdatedVSpec =  makeSpec(additionalRerenderedIndexes, additionalIndexes);
        render(secondUpdatedVSpec, {host: rendered, old: updatedVSpec});// Is this host right? it seems inconsistent and the source of our bug (as it is probably also misused in custom-elements)
    
        // Validate add items and changed order
        expect(container.innerHTML).toBe(
            [
                `<ul>`,
                ...additionalIndexes.map(index=>`<li id="${`li_${index}`}">${index}</li>`),
                `</ul>`
            ].join('')
        );
    
        // Validate that items were merely re-arranged and not re-created
        expect(additionalRerenderedIndexes.size).toBe(additionalIndexes.length);
        for(let i of initIndexes){
            let initRendered = initialRendered.get(i);
            let additionalRendered = additionalRerenderedIndexes.get(i);
            expect(initRendered === additionalRendered).toBe(true); // These should've still remained the same
        }
    
        // Revert back to the original
        render(initialVSpec, {host: rendered, old: secondUpdatedVSpec});// Is this host right? it seems inconsistent and the source of our bug (as it is probably also misused in custom-elements)
    
        // Validate reverting back to the original
        expect(container.innerHTML).toBe(
            [
                `<ul>`,
                ...initIndexes.map(index=>`<li id="${`li_${index}`}">${index}</li>`),
                `</ul>`
            ].join('')
        );
    });
});