@using Berufsschule_HAM.Helpers
@using Berufsschule_HAM.Services
@using Microsoft.AspNetCore.Html
@using Microsoft.AspNetCore.Mvc.Localization
@using Berufsschule_HAM.Models
@using System.Buffers.Text
@using System.Text.Json;
@using System.Text.Json.Serialization;
@model AdminSettingsModel
@inject IViewLocalizer T
@inject LdapService ldap
@{
    ViewData["Title"] = T["Admin settings"];
    List<string> supportedBarcodeTypes = ["code128c", "ean13", "ean8", "upc", "itf14", "itf"];
    string userImageCacheSize = ImageHelper.ToHumanReadableSize(ImageHelper.GetImageCacheSize());
}

<form id="updateSettings" style="margin-bottom: 4rem !important" method="post" asp-controller="Settings" asp-action="Admin">
    <h4 class="fw-bold">@T["General settings"]</h4>
    <div class="row g-3">
        <div class="col-md-3">
            <label class="form-label" for="updateHashAlgorithm">@T["Default hash algorithm"]</label>
            <select type="text" name="DefaultHashAlgorithm" id="updateHashAlgorithm" class="form-control">
                @foreach (string algorithm in ldap.HashAlgorithms.Keys)
                {
                    bool selected = algorithm == Model.DefaultHashAlgorithm;
                    <option value="@algorithm" selected="@selected">@algorithm</option>                    
                }
            </select>
        </div>
        <div class="col-md-3">
            <label class="form-label" for="updateBarcodeType">@T["Barcode type"]</label>
            <span 
                id="barcodeInfoIcon"
                class="ms-2 text-info"
                style="cursor: pointer;"
                data-bs-toggle="modal"
                data-bs-target="#barcodePreviewModal"
                id="barcodePreviewButton"
                title="Preview">
                <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16">
                    <path d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14zm0-13A6 6 0 1 1 8 14A6 6 0 0 1 8 2z"/>
                    <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.176-.304-.497L8.93 6.588zM9 4.5a1 1 0 1 1-2 0a1 1 0 0 1 2 0z"/>
                </svg>
            </span>
            <select type="text" name="BarcodeType" id="updateBarcodeType" class="form-control" />
                @foreach (string barcodeType in supportedBarcodeTypes)
                {
                    <option selected="@(Model.BarcodeType == barcodeType)" value="@barcodeType">@barcodeType.ToUpper()</option>
                }
            </select>
        </div>
        <div class="col-md-3">
            <label class="form-label" for="updateBarcodeText">@T["Barcode text"]</label>
            <input type="text" name="BarcodeText" id="updateBarcodeText" class="form-control" value="@Model.BarcodeText" />
        </div>
        <div class="col-md-4">
            <label class="form-label" for="updateMaxDownloadableUserImageSize">@T["Max downloadable user image size"]</label>
            <input type="number" id="updateMaxDownloadableUserImageSize" name="MaxDownloadableUserImageSize" class="form-control" value="@Model.MaxDownloadableUserImageSize" />
        </div>
        <div class="col-md-3">
            <label class="form-label" for="updateUserImagePreloadType">@T["User image preloading"]</label>
            <select type="text" name="UserImagePreloadType" id="updateUserImagePreloadType" class="form-control" />
                @foreach (UserImagePreloadType userImagePreloadType in Enum.GetValues(typeof(UserImagePreloadType)))
                {
                    <option selected="@(Model.UserImagePreloadType == userImagePreloadType)" value="@userImagePreloadType">@T["userImagePreloadType_" + userImagePreloadType.ToString()]</option>
                }
            </select>
        </div>
        <div class="col-md-4">
            <p class="form-label">@T["Current user image cache utilization:"] <span id="userImageCacheSize">@userImageCacheSize</span></p>
            <button class="form-control btn btn-danger" type="button" id="clearCacheBtn">@T["Clear user image cache"]</button>
        </div>
    </div>
    <div class="mt-3 p-2 bg border rounded d-flex justify-content-between align-items-center"
        data-bs-toggle="collapse"
        data-bs-target="#presetsCollapse"
        style="cursor: pointer;">

        <h4 class="fw-bold m-0">@T["Presets"]</h4>
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
            viewBox="0 0 16 16" class="chevron-svg">
            <path fill-rule="evenodd"
                d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
        </svg>
    </div>
    <div class="row g-3 collapse" id="presetsCollapse">
        @foreach (var preset in Model.Presets)
        {
            <div class="col-md-6">
                <div class="border rounded p-3 mb-3" data-preset-id="@(preset.Key)">
                    <label class="form-label" for="Presets.@(preset.Key).Key">@T["Preset name"]</label>
                    <input class="form-control mb-3" id="Presets.@(preset.Key).Key" name="Presets.@(preset.Key).Key" value="@preset.Key"/>
                    <label class="form-label">@T["Attributes"]</label>
                    @foreach (var attr in preset.Value.Attribute)
                    {
                        <div class="row mb-2" data-type="attribute">
                            <div class="col-md-3 mt-2">
                                <input class="form-control"
                                    name="Presets.@(preset.Key).Attribute.@(attr.Key).Key"
                                    value="@attr.Key" placeholder="@T["Name"]" aria-label="@T["Name"]" />
                            </div>
                            <div class="col-md-5 mt-2">
                                <input class="form-control"
                                    name="Presets.@(preset.Key).Attribute.@(attr.Key).Value"
                                    value="@attr.Value" placeholder="@T["Value"]" aria-label="@T["Value"]" />
                            </div>
                            <div class="col-md-4 mt-2">
                                <button type="button" class="btn btn-danger" data-type="deleteAttribute">@T["Delete attribute"]</button>
                            </div>
                        </div>
                    }
                    <div class="attributes"></div>
                    <div class="row mb-2">
                        <div class="col-md-8 mt-2">
                            <button type="button" class="btn btn-danger" data-type="deletePreset">@T["Delete preset"]</button>
                        </div>
                        <div class="col-md-4 ms-auto mt-2">
                            <button type="button" class="btn btn-primary" data-type="addAttribute">@T["Add attribute"]</button>
                        </div>
                    </div>
                </div>
            </div>
        }
        <div class="col-md-12 mt-2">
            <button type="button" class="btn btn-primary" data-type="addPreset">@T["Add preset"]</button>
        </div>
    </div>
    <button type="submit" class="btn btn-warning float-end mt-3">@T["Apply settings and update presets"]</button>
</form>

<script defer>

    document.getElementById("clearCacheBtn").addEventListener("click", async () => {
        try {
            const response = await fetch("/Settings/ClearUserImageCache", {
                method: "POST",
                headers: {
                    "X-Requested-With": "XMLHttpRequest"
                }
            });

            if (!response.ok) {
                throw new Error("Request failed: " + response.status);
            }

            document.getElementById("userImageCacheSize").textContent = "0 B";
            showToast('@T["Cache cleared successfully"]', 'success');
        } catch (err) {
            console.error(err);
            showToast('@T["Error contacting server"]', 'danger');
        }
    });

    setInterval(() => {
        fetch('/Settings/UserImageCacheSize', {
            method: 'POST'
        })
        .then(res => res.text())
        .then(text => {
            document.querySelector('#userImageCacheSize').textContent = text;
        })
        .catch(err => console.error('Cache-size fetch failed:', err));
    }, 1000);


    document.addEventListener('DOMContentLoaded', () => {
        const updateForm = document.getElementById('updateSettings');
        updateForm.addEventListener('submit', async e => {
            e.preventDefault();
            const url = `/Settings/Admin`;
            const dataFromEntries = Object.fromEntries(new FormData(updateForm).entries());
            var data = unflatten(dataFromEntries);
            var presets = {};
            for (var preset in data.Presets) {
                for (var attribute in data.Presets[preset].Attribute) {
                    var key = data.Presets[preset].Attribute[attribute].Key;
                    var value = data.Presets[preset].Attribute[attribute].Value;
                    delete(data.Presets[preset].Attribute[attribute]);
                    data.Presets[preset].Attribute[key] = value;
                }
                var presetKey = data.Presets[preset].Key;
                delete(data.Presets[preset].Key);
                var tempPreset = data.Presets[preset];
                delete(data.Presets[preset]);
                data.Presets[presetKey] = tempPreset;
            }
            var temp = data;
            data = {};
            data.AdminSettingsModel = temp;
            try {
                const response = await fetch(url, {
                    method: 'PUT',
                    headers: {
                        'Content-Type': 'application/json',
                        'Accept': 'application/json'
                    },
                    body: JSON.stringify(data)
                });

                const result = await response.json();

                if (result.Success) {
                    showToast('@T["Settings updated successfully"]', 'success');
                } else {
                    showToast(`${result.reason}: ${result.exception || '@T["Unknown error"]'}`, 'danger');
                }
            } catch (error) {
                console.error(error);
                showToast('@T["Error contacting server"]', 'danger');
            }
        });
    });


    function addAttribute(presetContainer, presetKey) {
        const attributeId = crypto.randomUUID();

        const row = document.createElement('div');
        row.classList.add('row', 'mb-2');

        row.innerHTML = `
            <div class="col-md-3">
                <input class="form-control"
                    name="Presets.${presetKey}.Attribute.${attributeId}.Key"
                    value="" />
            </div>
            <div class="col-md-5">
                <input class="form-control"
                    name="Presets.${presetKey}.Attribute.${attributeId}.Value"
                    value="" />
            </div>
            <div class="col-md-4">
                <button type="button" class="btn btn-danger btn-delete-attr">
                    ${presetContainer.dataset.deleteAttributeText}
                </button>
            </div>
        `;

        presetContainer.querySelector('.attributes').appendChild(row);
    }

    document.querySelectorAll('[data-bs-toggle="collapse"]').forEach(toggler => {
        toggler.addEventListener('click', async () => {
            const icon = toggler.querySelector('.chevron-svg');
            icon.classList.toggle('rotate');
            var target = document.querySelector(toggler.dataset.bsTarget);
            while (target.classList.contains('collapsing')) {
                await sleep(10);
            }
            icon.parentElement.classList.toggle("no-bottom-border");
            const collapseId = toggler.dataset.bsTarget.replace('#', '');
            const isCollapsed = target.classList.contains('show');
            // Update URL parameter
            const url = new URL(window.location);
            url.searchParams.set(collapseId, isCollapsed); // true = open, false = collapsed
            window.history.replaceState({}, '', url);
        });
    });

    document.addEventListener('DOMContentLoaded', () => {
        const collapseElements = document.querySelectorAll('.collapse');

        collapseElements.forEach(el => {
            const paramValue = new URL(window.location).searchParams.get(el.id);
            if (paramValue === 'true') {
                el.classList.add('show');
                const toggler = document.querySelector(`[data-bs-target="#${el.id}"]`);
                if (toggler) {
                    toggler.querySelector('.chevron-svg')?.classList.add('rotate');
                    toggler.classList.add('no-bottom-border');
                }
            } else {
                el.classList.remove('show');
            }
        });
    });

    document.querySelectorAll('button[data-type="addAttribute"]').forEach(btn => {
        addAddAttributeEventListener(btn);
    });

    document.querySelectorAll('button[data-type="deleteAttribute"]').forEach(btn => {
        addRemoveAttributeEventListener(btn);
    });

    document.querySelectorAll('button[data-type="deletePreset"]').forEach(btn => {
        addDeletePresetEventListener(btn);
    });

    document.querySelectorAll('button[data-type="addPreset"]').forEach(btn => {
        addAddPresetEventListener(btn);
    });

    function addAddAttributeEventListener(button) {
        button.addEventListener('click', e => {
            const presetContainer = e.target.closest('.border.rounded.p-3.mb-3');
            if (!presetContainer) return;

            const presetKey = presetContainer.getAttribute("data-preset-id");
            if (!presetKey) return;

            // Container für Attribute suchen
            let attributesContainer = presetContainer.querySelector('.attributes');
            if (!attributesContainer) {
                // Falls nicht vorhanden -> dynamisch anlegen (optional)
                attributesContainer = document.createElement('div');
                attributesContainer.classList.add('attributes');
                presetContainer.insertBefore(attributesContainer, presetContainer.querySelector('.row.mb-4'));
            }

            const attributeId = crypto.randomUUID();

            const row = document.createElement('div');
            row.classList.add('row', 'mb-2');
            row.setAttribute('data-type', 'attribute');

            row.innerHTML = `
                <div class="col-md-3">
                    <input class="form-control"
                        name="Presets.${presetKey}.Attribute.${attributeId}.Key"
                        value="" />
                </div>
                <div class="col-md-5">
                    <input class="form-control"
                        name="Presets.${presetKey}.Attribute.${attributeId}.Value"
                        value="" />
                </div>
                <div class="col-md-4">
                    <button type="button" class="btn btn-danger" data-type="deleteAttribute">
                        ${presetContainer.dataset.deleteAttributeText || 'Delete attribute'}
                    </button>
                </div>
            `;

            attributesContainer.appendChild(row);

            // Delete-Button Eventlistener aktivieren
            const deleteButton = row.querySelector('button[data-type="deleteAttribute"]');
            addRemoveAttributeEventListener(deleteButton);
        });
    }

    function addRemoveAttributeEventListener(button) {
        button.addEventListener('click', e => {
            const row = e.target.closest('div[data-type="attribute"]');
            row.remove();
        });
    }

    function addDeletePresetEventListener(button) {
        button.addEventListener('click', e => {
            const presetContainer = e.target.closest('.col-md-6');
            if (!presetContainer) return;
            presetContainer.remove();
        });
    }

    function addAddPresetEventListener(button) {
        button.addEventListener('click', e => {
            // Presets-Container: der nächste Block über dem Button, der die Presets enthält
            const presetsButton = button.closest('button[data-type="addPreset"]');
            if (!presetsButton) return;

            const presetId = crypto.randomUUID();

            // Preset-Block erstellen
            const presetDiv = document.createElement('div');
            presetDiv.classList.add('col-md-6');
            presetDiv.innerHTML = `
                <div class="border rounded p-3 mb-3" data-preset-id="${presetId}">
                    <label class="form-label" for="Presets.${presetId}.Key">@T["Preset name"]</label>
                    <input class="form-control mb-3" id="Presets.${presetId}.Key" name="Presets.${presetId}.Key" value=""/>
                    <label class="form-label">@T["Attributes"]</label>
                    <div class="attributes"></div>
                    <div class="row mb-4">
                        <div class="col-md-4">
                            <button type="button" class="btn btn-danger" data-type="deletePreset">Delete preset</button>
                        </div>
                        <div class="col-md-4 ms-auto">
                            <button type="button" class="btn btn-primary" data-type="addAttribute">Add attribute</button>
                        </div>
                    </div>
                </div>
            `;

            // Einfach ans Ende der Container-Liste hängen
            presetsButton.parentElement.parentElement.insertBefore(presetDiv, presetsButton.parentElement);

            // Eventlistener für den neuen Preset-Block aktivieren
            const addAttrBtn = presetDiv.querySelector('button[data-type="addAttribute"]');
            const deletePresetBtn = presetDiv.querySelector('button[data-type="deletePreset"]');

            addAddAttributeEventListener(addAttrBtn);
            addDeletePresetEventListener(deletePresetBtn);
        });
    }
</script>

<style defer>
    .chevron-svg {
        transition: transform 0.2s ease;
    }

    .chevron-svg.rotate {
        transform: rotate(180deg);
    }

    .no-bottom-border {
        border-bottom: none !important;
        border-radius: 0.5rem 0.5rem 0 0 !important;
    }
</style>


<div class="modal modal-lg fade" id="barcodePreviewModal" tabindex="-1" aria-hidden="true" aria-label="@T["Barcode preview"]">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-header bg-info text-dark">
                <h3 class="modal-title">@T["Barcode preview"]</h5>
                <button type="button" class="btn-close btn-close-white" style="filter: invert(0);" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>

            <div class="modal-body text-center row">
            </div>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/jsbarcode@3.11.6/dist/JsBarcode.all.min.js" defer></script>

<script defer>
    document.addEventListener('DOMContentLoaded', () => {
        var barcodeTypes = @Html.Raw(JsonSerializer.Serialize(supportedBarcodeTypes));
        const modalContent = document.querySelector("#barcodePreviewModal .modal-content");
        var body = modalContent.querySelector('.modal-body');
        barcodeTypes.forEach(barcodeType => {
            const divCol = document.createElement('div');
            divCol.classList.add("col-md-6");
            const label = document.createElement('label');
            label.classList.add("form-label", "w-100");
            label.textContent = barcodeType.toUpperCase();
            const img = document.createElement('img');
            img.id = barcodeType;
            img.alt = "Preview";
            img.style.maxWidth = "100%";
            img.style.border = "1px solid #ddd";
            img.style.padding = "0.5rem";
            img.style.borderRadius = ".25rem";
            img.classList.add("mb-3");
            divCol.appendChild(label);
            divCol.appendChild(img);
            body.appendChild(divCol);

            JsBarcode(`#${barcodeType}`, getBarcodeValue(barcodeType, "123456789"), {
                format: barcodeType,
                lineColor: "#000",
                width: 2,
                height: 80,
                displayValue: true
            });
        });
    });
</script>