/* Define a web component providing a settable and selectable list
 $("symList").setData(r, append = false);
 where r is array of objects with properties name,detail,kind

https://stackoverflow.com/questions/50404970/web-components-pass-data-to-and-from
https://www.w3schools.com/howto/howto_js_treeview.asp
*/
class ListComponent extends HTMLElement {
    #shadow;
    #data;
    #iconKinds; //array from kind integer to codicon name
    constructor() {
        super();
        this.#shadow = this.attachShadow({ mode: "open", delegatesFocus: true });
        this.#data = [];
        // codicons kind 
        this.#iconKinds = [
                'symbol-file',
                'symbol-class',
                'symbol-namespace',
                'symbol-structure',
                'symbol-class',
                'symbol-method',
                'symbol-property',
                'symbol-field',
                'symbol-method-arrow',
                'symbol-enum',
                'symbol-interface',
                'symbol-method',
                'symbol-variable',
                'symbol-constant',
                'symbol-string',
                'symbol-numeric',
                'symbol-boolean',
                'symbol-array',
                'symbol-structure',
                'symbol-key',
                'dash',
                'symbol-enum-member',
                'symbol-misc',
                'symbol-event',
                'symbol-operator',
                'symbol-parameter'
            ];
        this.render();
    }

    setData(newData,  append = false) {
        if (!Array.isArray(newData)) {
            console.warn("Invalid format, expected an array.");
            return;
        }
       
        this.#data = append ? this.#data.concat(newData) : structuredClone(newData);
        this.render();
    }

    set data(value) {
        this.setData(value, false);
    }
    get data() {
        return this.#data;
    }

    /* Render the list items #data */
    render() {
        // eventhandler for click and keyboard, updates usage of selected class and raises event
        const select = e => {
            if(e.type ==="keyup" && !(e.key==="Enter" )) return;
            this.#shadow.querySelectorAll('li.selected').forEach(item => { item.className = ''; });
            e.currentTarget.className = 'selected';
            const i=e.currentTarget.getAttribute("data-index")
            console.log('Item index clicked:', i,this.#data[i]);
            // You can dispatch a custom event here if needed.
            this.dispatchEvent(new CustomEvent('itemSelected', {
                detail: this.#data[i],
                bubbles: true,
                composed: true
            }));
        };
        // create list and items
         const list = document.createElement('ul');
        list.style = "overflow: auto;"; 
        this.#data.forEach((item, index) => {
            const listItem = document.createElement('li');
            const icon=this.#iconKinds[item.kind];
            listItem.setAttribute("tabindex", "0")
            listItem.setAttribute("data-index", index)
            listItem.innerHTML = `<i  class='codicon codicon-${icon}' 
            title='${icon}'></i>
            <span >${item.name} - ${item.detail}</span>`;

            listItem.addEventListener('click', select);
             listItem.addEventListener('keyup', select);
            list.appendChild(listItem);
        });

        this.#shadow.innerHTML = '';
        const style = document.createElement('style');
        style.textContent = `
      @import url("../codicon@0.0.40/codicon.css");  
      ul { list-style-type: none; padding:0;margin:0;overflow: auto; 
      background-color: #f8f9fa;font-size: 80%;}
      li { padding: 0 0 0 2px;  cursor: pointer; width:100%; }
      li:not(.selected) :hover { background-color:  #ccc; }
      .selected {  background-color: #0d6efd;color: #ffff;}
      i {vertical-align: middle;}
    `;
        this.#shadow.appendChild(style);
        this.#shadow.appendChild(list);
    }

    /* Render an error message if JSON fetching fails */
    renderError(error) {
        this.#shadow.innerHTML = `<p>Error loading data: ${error.message}</p>`;
    }
}

/* Define the new custom element */
customElements.define('qd-list', ListComponent);

class PanelComponent extends HTMLElement {
    #shadow;
    #data;
    #iconKinds; //array from kind integer to codicon name
    constructor() {
        super();
        this.#shadow = this.attachShadow({ mode: "open", delegatesFocus: true });
        this.#data = [];
        this.#iconKinds = [];
        this.render();
    }

    setData(newData, append = false) {
        if (!Array.isArray(newData)) {
            console.warn("Invalid format, expected an array.");
            return;
        }
        this.#data = append ? this.#data.concat(newData) : structuredClone(newData);
        this.render();
    }

    set data(value) {
        this.setData(value, false);
    }
    get data() {
        return this.#data;
    }

    /* Render the list items #data */
    render() {
        const list = document.createElement('ul');
        list.style = "overflow: auto;";

        const select = e => {
            if(e.type ==="keyup" && !(e.key==="Enter" )) return;
            this.#shadow.querySelectorAll('li.selected').forEach(item => { item.className = ''; });
            e.currentTarget.className = 'selected';
            const i=e.currentTarget.getAttribute("data-index")
            console.log('Item index clicked:', i,this.#data[i]);
            // You can dispatch a custom event here if needed.
            this.dispatchEvent(new CustomEvent('itemSelected', {
                detail: this.#data[i],
                bubbles: true,
                composed: true
            }));
        };
        this.#data.forEach((item, index) => {
            const listItem = document.createElement('li');
            const icon=this.#iconKinds[item.kind];
            listItem.setAttribute("tabindex", "0")
            listItem.setAttribute("data-index", index)
            listItem.innerHTML = `<span title='A ${icon}'>XX<i  class='codicon codicon-${icon}' >*</i></span>
            <span >${item.name} - ${item.detail}</span>`;

            listItem.addEventListener('click', select);
             listItem.addEventListener('keyup', select);
            list.appendChild(listItem);
        });

        this.#shadow.innerHTML = '';
        const style = document.createElement('style');
        style.textContent = `
      @import url("../codicon@0.0.40/codicon.css");  
      ul { list-style-type: none; padding:0;margin:0; 
      background-color: #e3e4e4ff;font-size: 80%;  scrollbar-color: #000077 #bada55;}
      li { padding: 0 0 0 2px; border-bottom: 1px solid #ccc; cursor: pointer; width:100%; }
      li:not(.selected) :hover { background-color:  #ccc; }
      .selected {  background-color: #0d6efd;color: #ffff;}
      i {vertical-align: middle;}
    `;
        this.#shadow.appendChild(style);
        this.#shadow.appendChild(list);
    }

    /* Render an error message if JSON fetching fails */
    renderError(error) {
        this.#shadow.innerHTML = `<p>Error loading data: ${error.message}</p>`;
    }
}

/* Define the new custom element */
customElements.define('qd-panel', PanelComponent);

