import '../../../literyz-js/extensions.dist.js';

import ContentService from './content-service.js';


class ImgContentService extends ContentService {
    #containerPanel = null;
    #popupService = null;


    constructor(popupService) {
        super();

        this.#popupService = popupService;
    }

    InitialiseComponents() {
        const a = this;

        a.Clear();

        a.#initialiseComponents_Options();
        a.#initialiseComponents_Filters();

        a.Button1.addEventListener('click', async function (e) {
            a.Button2.disabled = true;

            a.TextBox1.value = "";

            await a.Search();

            a.Button2.disabled = false;
        });

        a.Button2.addEventListener('click', async function (e) {
            a.Button2.disabled = true;

            await a.Search();

            a.Button2.disabled = false;
        });
    }

    #initialiseComponents_Options() {
        const a = this;

        let col1 = "";
        col1 += a.GenerateCheckBox(203, "Sort By Source URL", true);
        col1 += a.GenerateCheckBox(204, "Resolve Relative URL", false);

        let col2 = "";
        col2 += a.GenerateCheckBox(202, "Trim Alternate Text", true);

        let html = a.GenerateCols(col1, col2);

        a.SetHtml(a.Panel1, html);
    }

    #initialiseComponents_Filters() {
        const a = this;

        let col1 = "";
        col1 += a.GenerateCheckBox(212, "Hide External Links", false);
        col1 += a.GenerateCheckBox(205, "Hide Duplicates", true);
        col1 += a.GenerateCheckBox(214, "Hide Blank Alternate Text", false);
        col1 += a.GenerateCheckBox(215, "Hide Blank Source URL", true);

        let col2 = "";
        col2 += a.GenerateCheckBox(206, "Show Alternative Text", true);
        col2 += a.GenerateCheckBox(207, "Show Source Set", false);
        col2 += a.GenerateCheckBox(208, "Show Image Map", false);
        // col2 += a.GenerateCheckBox(209, "Show Width", false);
        // col2 += a.GenerateCheckBox(210, "Show Height", false);
        col2 += a.GenerateCheckBox(210, "Show Count", false);

        let html = a.GenerateCols(col1, col2);

        a.SetHtml(a.Panel2, html);
    }


    get Button1() {
        const a = this;

        if (a.Container == null) {
            return null;
        }

        return a.Container.querySelectorAll("button")[0];
    }

    get Button2() {
        const a = this;

        if (a.Container == null) {
            return null;
        }

        return a.Container.querySelectorAll("button")[1];
    }

    get Container() {
        const a = this;

        if (a.#containerPanel == null) {
            a.#containerPanel = document.getElementById("nav-images");
        }

        return a.#containerPanel;
    }

    get Label1() {
        const a = this;

        if (a.Container == null) {
            return null;
        }

        return a.Container.querySelectorAll("[role='label']")[0];
    }

    get MemoBox1() {
        const a = this;

        if (a.Container == null) {
            return null;
        }

        return a.Container.querySelectorAll("textarea")[0];
    }

    get Panel1() {
        const a = this;

        if (a.Container == null) {
            return null;
        }

        return a.Container.querySelectorAll("div[role='options']")[0];
    }

    get Panel2() {
        const a = this;

        if (a.Container == null) {
            return null;
        }

        return a.Container.querySelectorAll("div[role='filters']")[0];
    }

    get Table1() {
        const a = this;

        if (a.Container == null) {
            return null;
        }

        return a.Container.querySelectorAll("table")[0];
    }

    get TextBox1() {
        const a = this;

        if (a.Container == null) {
            return null;
        }

        return a.Container.querySelectorAll("input[role='textbox']")[0];
    }


    Clear() {
        const a = this;

        a.Table1.style.display = 'none';
        a.MemoBox1.style.display = 'none';

        a.SetHtml(a.Panel1, "");
        a.SetHtml(a.Panel2, "");
    }

    async Search() {
        const a = this;

        a.Label1.innerText = "";

        a.Table1.style.display = 'none';
        a.MemoBox1.style.display = 'none';

        const result = await a.#popupService.GetImages();
        const totalCount = result.length;

        const newResults = await a.#filterResult(result.copy());

        if (newResults.length == totalCount) {
            a.Label1.innerText = "Showing " + totalCount + " result" + (totalCount == 1 ? "" : "s");
        } else {
            a.Label1.innerText = "Showing " + newResults.length + " of " + totalCount + " result" + (totalCount == 1 ? "" : "s");
        }

        switch (a.#getComboBox(2)) {
            case "table":
                a.#renderTable(newResults);
                break;
            case "csv":
                a.#renderCSV(newResults);
                break;
            case "links":
                a.#renderLinks(newResults);
                break;
            default:
                break;
        }
    }

    async #filterResult(items) {
        const a = this;
        const currentUrl = await a.#popupService.GetLocation();
        const currentHostname = (new URL(currentUrl)).hostname;

        let result = [];

        for (let i=0; i<items.length; i++) {
            const item = items[i];

            // Hide source
            if (a.#getCheckBox(215)) {
                if (String.isNullOrWhitespace(item.src)) {
                    continue;
                }
            }

            const absoluteUrl = new URL(item.src, currentUrl);

            // Hide external links
            if (a.#getCheckBox(212)) {
                if (currentHostname != absoluteUrl.hostname) {
                    continue;
                }
            }

            // Hide blank alternative text
            if (a.#getCheckBox(214)) {
                if (String.isNullOrWhitespace(item.alt)) {
                    continue;
                }
            }

            // Resolve source
            const src = (a.#getCheckBox(204) ? absoluteUrl.href : item.src);
            const alt = (a.#getCheckBox(202) ? item.alt.trim() : item.alt);

            // Search term
            if (!String.isNullOrWhitespace(a.TextBox1.value)) {
                if (a.#getComboBox(201) == "alt") {
                    if (!alt.toLowerCase().includes(a.TextBox1.value.toLowerCase())) {
                        continue;
                    }
                } else {
                    if (!src.toLowerCase().includes(a.TextBox1.value.toLowerCase())) {
                        continue;
                    }
                }
            }

            result.push({
                src: src,
                alt: (a.#getCheckBox(206) ? alt : ""),
                srcset: (a.#getCheckBox(207) ? item.srcset : ""),
                usemap: (a.#getCheckBox(208) ? item.usemap : ""),
                occurrence: ""
              });
        }

        // Show occurrence
        if (a.#getCheckBox(210)) {
            // Calc occurrences, store in cache
            let occurrenceCache = [];
            for (let i=0; i<result.length; i++) {
                const occurrence = result.filter(item => JSON.stringify(item) === JSON.stringify(result[i])).length;

                occurrenceCache.push(occurrence);
            }

            // Update result with occurrence
            for (let i=0; i<result.length; i++) {
                result[i].occurrence = occurrenceCache[i];
            }
        }

        // Hide duplicates
        if (a.#getCheckBox(205)) {
            result = result.distinct();
        }

        // Sort by source
        if (a.#getCheckBox(203)) {
            result = result.orderBy("src");
        }

        return result;
    }

    #generateTHeader() {
        const a = this;
        const columns = [
            { id: 206, name: "Alternative Text" },
            { id: 207, name:  "Source Set" },
            { id: 208, name:  "Image Map" },
            { id: 210, name:  "Count" }
        ];

        let html = "";
        html += "<th>Source</th>";

        for (let i=0; i<columns.length; i++) {
            if (a.#getCheckBox(columns[i].id)) {
                html += "<th>" + columns[i].name + "</th>";
            }
        }

        return html;
    }

    #getCheckBox(num) {
        const a = this;

        if (a.Container == null) {
            return false;
        }

        const result = a.Container.querySelectorAll("input[name='checkbox" + num + "']");
        if (result.length <= 0) {
            return false;
        }

        return result[0].checked;
    }

    #getComboBox(num) {
        const a = this;

        if (a.Container == null) {
            return "";
        }

        const result = a.Container.querySelectorAll("select[name='comboBox" + num + "']");
        if (result.length <= 0) {
            return "";
        }

        return result[0].value;
    }

    #renderTable(results) {
        const a = this;
        const thead = a.Table1.querySelectorAll("thead")[0];
        const tbody = a.Table1.querySelectorAll("tbody")[0];

        thead.innerHTML = "";
        tbody.innerHTML = "";

        a.Table1.style.display = 'table';

        // Write thead
        thead.innerHTML = "<tr>" + a.#generateTHeader() + "</tr>";

        // Write tbody
        for (let i=0; i<results.length; i++) {
            const item = results[i];

            let row = [ item.src ];

            if (a.#getCheckBox(206)) {
                row.push(item.alt);
            }

            if (a.#getCheckBox(207)) {
                row.push(item.srcset);
            }

            if (a.#getCheckBox(208)) {
                row.push(item.usemap);
            }

            if (a.#getCheckBox(210)) {
                row.push(item.occurrence);
            }

            tbody.innerHTML += a.GenerateRow(row);
        }
    }

    #renderCSV(results) {
        const a = this;

        a.MemoBox1.value = "";
        a.MemoBox1.style.display = 'inline-block';

        for (let i=0; i<results.length; i++) {
            const item = results[i];

            let row = [ item.src ];

            if (a.#getCheckBox(206)) {
                row.push(item.alt);
            }

            if (a.#getCheckBox(207)) {
                row.push(item.srcset);
            }

            if (a.#getCheckBox(208)) {
                row.push(item.usemap);
            }

            if (a.#getCheckBox(210)) {
                row.push(item.occurrence);
            }

            a.MemoBox1.value += a.GenerateCSVLine("\t", row);
            a.MemoBox1.value += "\n";
        }
    }

    #renderLinks(results) {
        const a = this;

        a.MemoBox1.value = "";
        a.MemoBox1.style.display = 'inline-block';

        for (let i=0; i<results.length; i++) {
            const item = results[i];

            a.MemoBox1.value += a.GenerateCSVLine("\t", [ item.src ]);
            a.MemoBox1.value += "\n";
        }
    }

}


export default ImgContentService;