/* ===================== AUTOGENERATED SOURCE IMPORT ===================== */

import Template from "/emcJS/util/html/template/HTMLTemplate.js";

const TPL = new Template(`
    <div id="title">
        <emc-searchinput id="search"></emc-searchinput>
    </div>
    <div id="body">
        <div id="list">
            <slot></slot>
        </div>
    </div>
`);

import GlobalStyle from "/emcJS/util/html/template/CSSTemplate.js";

const STYLE = new GlobalStyle(`
    :host {
        display: inline-flex;
        flex-direction: column;
        width: 300px;
        height: 300px;
    }
    #title {
        display: flex;
        align-items: center;
        width: 100%;
        padding: 10px;
        font-size: 1.5em;
        line-height: 1em;
        border-bottom: solid 1px var(--page-text-color, #000000);
        user-select: none;
    }
    #text {
        display: block;
        flex: 1;
        font-size: .8em;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    :host([access="opened"]) #text {
        color: var(--world-entry-status-opened-color, #777777);
    }
    :host([access="available"]) #text {
        color: var(--world-entry-status-available-color, #00ff00);
    }
    :host([access="unavailable"]) #text {
        color: var(--world-entry-status-unavailable-color, #ff0000);
    }
    :host([access="possible"]) #text {
        color: var(--world-entry-status-possible-color, #ffff00);
    }
    #title > .button {
        width: 38px;
        height: 38px;
        padding: 4px;
        margin-left: 8px;
        border: solid 2px var(--navigation-back-color, #ffffff);
        border-radius: 10px;
    }
    #body {
        flex: 1;
        overflow-y: auto;
        overflow-x: hidden;
    }
    #list {
        display: content;
    }
    #hint {
        margin-left: 5px;
    }
    #body .button.hidden,
    :host(:not([ref])) #back {
        display: none;
    }
    .button,
    ::slotted(*) {
        border-bottom: solid 1px var(--list-border-bottom-color, #000000);
        border-top: solid 1px var(--list-border-top-color, #000000);
    }
`);

/* ======================================================================= */

// frameworks
import ElementManager from "/emcJS/util/html/ElementManager.js";
import EventMultiTargetManager from "/emcJS/util/event/EventMultiTargetManager.js";
import EventTargetManager from "/emcJS/util/event/EventTargetManager.js";
import BusyIndicatorManager from "/emcJS/util/BusyIndicatorManager.js";
import Panel from "/emcJS/ui/layout/Panel.js";
import {
    nodeTextComparator,
    sortChildren
} from "/emcJS/util/helper/ui/NodeListSort.js";
import {
    getInnerText
} from "/emcJS/util/helper/ui/ExtractText.js";
import {
    debounce
} from "/emcJS/util/Debouncer.js";
import i18n from "/emcJS/util/I18n.js";
import SearchAnd from "/emcJS/util/search/SearchAnd.js";
import UIRegistry from "../../../registry/UIRegistry.js";
import WorldResource from "../../../data/resource/WorldResource.js";
import LocationStateManager from "../../../statemanager/world/location/LocationStateManager.js";
import SettingsObserver from "../../../util/observer/SettingsObserver.js";
import "/emcJS/ui/input/SearchField.js";
import "./components/entries/LocationListLocation.js";

const locationistSortedObserver = new SettingsObserver("sort_locationlist_by_access");

const LOCATIONS = WorldResource.get("locations");

class ListEntryElementManager extends ElementManager {

    composer(key, params) {
        const uiReg = UIRegistry.get("locationlist-location");
        if (uiReg != null) {
            return uiReg.create(params.type, key);
        }
    }

}

// TODO use dataview/datalist
export default class LocationList extends Panel {

    #elementManager;

    #listEventManager = new EventMultiTargetManager();

    #i18nEventManager = new EventTargetManager(i18n);

    constructor() {
        super();
        this.shadowRoot.append(TPL.generate());
        STYLE.apply(this.shadowRoot);
        /* --- */
        this.#elementManager = new ListEntryElementManager(this);
        /* search */
        const searchEl = this.shadowRoot.getElementById("search");
        searchEl.addEventListener("change", (event) => {
            const all = this.querySelectorAll("[ref]");
            if (event.value) {
                const regEx = new SearchAnd(event.value);
                for (const el of all) {
                    const value = el.dataset.filtervalue ?? getInnerText(el);
                    if (regEx.test(value)) {
                        el.style.display = "";
                    } else {
                        el.style.display = "none";
                    }
                }
            } else {
                for (const el of all) {
                    el.style.display = "";
                }
            }
        });
        /* --- */
        this.#i18nEventManager.set("language", () => {
            this.#sort();
        });
        this.#i18nEventManager.set("translation", () => {
            this.#sort();
        });
        /* --- */
        this.#listEventManager.set("access", () => {
            if (locationistSortedObserver.value) {
                this.#sort();
            }
        });
        /* --- */
        if (locationistSortedObserver.value) {
            this.#elementManager.registerSortFunction(this.#sortByAccessAndNameFunction);
        } else {
            this.#elementManager.registerSortFunction(this.#sortByNameFunction);
        }
        locationistSortedObserver.onChange(() => {
            if (locationistSortedObserver.value) {
                this.#elementManager.registerSortFunction(this.#sortByAccessAndNameFunction);
            } else {
                this.#elementManager.registerSortFunction(this.#sortByNameFunction);
            }
        });
        this.#elementManager.addEventListener("afterrender", () => {
            BusyIndicatorManager.unbusy();
        });
    }

    load() {
        /* init list */
        this.#buildList();
    }

    unload() {
        /* init list */
        this.#elementManager.manage([]);
    }

    #sort = debounce(() => {
        this.#elementManager.sort();
    }, 1000);

    async #buildList() {
        await BusyIndicatorManager.busy();
        const elManagerData = [];
        this.#listEventManager.clearTargets();
        for (const ref in LOCATIONS) {
            const loc = LOCATIONS[ref];
            const state = LocationStateManager.get(ref);
            this.#listEventManager.addTarget(state);
            elManagerData.push({
                key: ref,
                type: loc.type,
                state
            });
        }
        // this.classList.toggle("empty", !hasElements);
        this.#elementManager.manage(elManagerData);
        sortChildren(this);
    }

    #sortByNameFunction(entry0, entry1) {
        const {element: el0} = entry0;
        const {element: el1} = entry1;
        return nodeTextComparator(el0, el1);
    }

    #sortByAccessAndNameFunction(entry0, entry1) {
        const {data: data0, element: el0} = entry0;
        const {data: data1, element: el1} = entry1;
        if (data0.state.access.value.orderValue < data1.state.access.value.orderValue) {
            return -1;
        }
        if (data0.state.access.value.orderValue > data1.state.access.value.orderValue) {
            return 1;
        }
        return nodeTextComparator(el0, el1);
    }

}

Panel.registerReference("locationlist", LocationList);
customElements.define("gt-locationlist", LocationList);
