{% extends 'config/base.html.j2' %}

{% block config_base %}
{% if is_xhr is not defined %}
<div id="page-config" class="config-page">
{% endif %}
    <p>
    {%- trans %}
        On this tab you can set up other turris devices which can be controlled
        by this device. You need to generate token on the remote tab on the device
        you wan't to control. And insert the token here.
    {%- endtrans %}
    </p>
    <h3>{% trans %}Add subordinate device{% endtrans %}</h3>
    <form id="main-form" class="config-form" action="{{ request.fullpath }}" method="post" enctype="multipart/form-data" autocomplete="off" novalidate>
        {% include '_messages.html.j2' %}
        <input type="hidden" name="csrf_token" value="{{ get_csrf_token() }}">
        {% for field in form.active_fields %}
            {% include '_field.html.j2' %}
        {% endfor %}
        <div id="{{ 'form-%s-buttons' % form.name }}" class="form-buttons">
            <button type="submit" name="send" class="button"><i class="fas fa-upload"></i> {% trans %}Upload token{% endtrans %}</button>
        </div>
    </form>
{% if is_xhr is not defined %}
    <h3>{% trans %}Subordinate devices{% endtrans %}</h3>
    {% set subpage = request.params.get("view", "subordinates") %}
    <a href="{{ request.fullpath }}?view=subordinates" class="button{% if subpage == "subordinates" %} disabled{% endif %}">{% trans %}Subordinates{% endtrans %}</a>
    <a href="{{ request.fullpath }}?view=wifi" class="button{% if subpage == "wifi" %} disabled{% endif %}">{% trans %}Wifi{% endtrans %}</a>
    <hr>
    <div id="subordinates-message"></div>
    <div id="subordinates-table">
    {% trans %}Loading subordinates...{% endtrans %}
    </div>
    <br />
    <div id="subordinates-edit">
    </div>
    <script>
        Foris.queryBackendWifi = async (controller_id) => {
            let run = async () => {
                try {
                    resp = await Foris.performBackendQuery(controller_id, "wifi", "get_settings");
                    $(`#sub-${controller_id}`).find(".wifi-count").text(resp.devices.length);
                    let channels = [];
                    for (let device of resp.devices) {
                        if (device.enabled) {
                            channels.push(device.channel == 0 ? "*": device.channel);
                        }
                    };
                    $(`#sub-${controller_id}`).find(".wifi-channels").text(channels.join(", "));
                } catch(err) {
                    $(`#sub-${controller_id}`).find(".wifi-count").text("?");
                    $(`#sub-${controller_id}`).find(".wifi-channels").text("?");
                }
            };
            run();  // call async don't wait for it
        };
        Foris.subordinatesGetView = () => (new URLSearchParams(window.location.search)).get("view") || "subordinates";
        Foris.loadSubordinatesList = async () => {
            let urlParams = new URLSearchParams(window.location.search);
            let resp = await $.get('{{ url("config_ajax", page_name="subordinates") }}', {action: "list", view: Foris.subordinatesGetView()});
            $("#subordinates-table").replaceWith(resp);
            Foris.overrideSubordinatesButtons();
            Foris.setSubordinatesTimeouts();
        }
        Foris.setSubordinatesTimeouts = () => {
            for (timeout in Foris.subordinateKeepAliveTimeouts) {
                clearTimeout(Foris.subordinateKeepAliveTimeouts[timeout]);
            }
            Foris.subordinateKeepAliveTimeouts = {};
            $(".sub-connection").each((idx, val) => {
                let id = $(val).attr("id");
                if (id) {
                    Foris.subordinateSetKeepAliveTimeout(id.replace('sub-', ''));
                }
            });
        };
        Foris.overrideSubordinatesEditButton = async () => {
            $("#subordinates-edit form").submit(async (e) => {
                e.preventDefault();
                let form = $(e.currentTarget);
                resp = $.ajax({
                    type: "POST",
                    url: form.attr('action'),
                    data: form.serialize()
                });
                form.find("input, select, button").attr("disabled", "disabled");
                try {
                    let new_form = await resp;
                    $("#subordinates-edit").replaceWith(new_form);
                    await Foris.suboridnatesOverrideEditClose();
                    await Foris.overrideSubordinatesEditButton();
                    await Foris.loadSubordinatesList();
                    $(".subordinate-buttons button").hide();
                } catch(err) {
                    alert(err);
                }
            });
        };
        Foris.overrideSubordinatesButtons = async () => {
            $(".subordinate-buttons").submit(async (e) => {
                e.preventDefault();
                let form = $(e.currentTarget);
                let action = $(e.originalEvent.explicitOriginalTarget).val();
                let form_data = {};
                let serialized = form.serializeArray();
                for (record in serialized) {
                    form_data[serialized[record].name] = serialized[record].value;
                }
                let controller_id = form_data.controller_id;
                let renderResponse = (resp) => {
                    $("#subordinates-message").replaceWith(resp);
                };
                let resp = null;
                switch (action) {
                    case "enable":
                        resp = await $.ajax({
                            type: "POST",
                            url: form.attr('action'),
                            data: `${form.serialize()}&action=${action}`
                        });
                        renderResponse(resp);
                        break;
                    case "disable":
                        resp = $.ajax({
                            type: "POST",
                            url: form.attr('action'),
                            data: `${form.serialize()}&action=${action}`
                        });
                        renderResponse(resp);
                        break;
                    case "delete":
                        resp = $.ajax({
                            type: "POST",
                            url: form.attr('action'),
                            data: `&csrf_token=${form_data["csrf_token"]}&controller_id=${form_data["controller_id"]}&action=${action}`
                        });
                        renderResponse(resp);
                        break;
                    case "edit":

                        switch (Foris.subordinatesGetView()) {
                            case "subordinates":
                                if (form.attr("class").includes("subsub-form")) {
                                    resp = await $.ajax({
                                        type: "POST",
                                        url: '{{ url("config_ajax_form", page_name="subordinates", form_name="subsub-form") }}',
                                        data: `&csrf_token=${form_data["csrf_token"]}&controller_id=${form_data["controller_id"]}&_update=1`,
                                    });
                                } else {
                                    resp = await $.ajax({
                                        type: "POST",
                                        url: '{{ url("config_ajax_form", page_name="subordinates", form_name="sub-form") }}',
                                        data: `&csrf_token=${form_data["csrf_token"]}&controller_id=${form_data["controller_id"]}&_update=1`,
                                    });
                                }
                                break;
                            case "wifi":
                                resp = await $.ajax({
                                    type: "POST",
                                    url: '{{ url("config_ajax_form", page_name="subordinates", form_name="wifi-form") }}',
                                    data: `&csrf_token=${form_data["csrf_token"]}&_controller_id=${form_data["controller_id"]}&_update=1`,
                                });
                        }
                        Foris.subordinateInEditMode = true;
                        await $("#subordinates-edit").promise();
                        $("#subordinates-edit").replaceWith(resp);
                        $(".subordinate-buttons button").hide('slow');
                        await $(".subordinate-buttons button").promise();
                        $("#subordinates-edit").show('slow');
                        await $("#subordinates-edit").promise();
                        await Foris.suboridnatesOverrideEditClose();
                        Foris.overrideSubordinatesEditButton();
                        return;
                }
                $(".subordinate-buttons button").prop('disabled', true);
            });
        };
        Foris.suboridnatesOverrideEditClose = async () => {
            $("#subordinates-edit").find("a.button").click(async (e) => {
                Foris.subordinateInEditMode = false;
                e.preventDefault();
                $("#subordinates-edit").hide('slow');
                await $("#subordinates-edit").promise();
                $("#subordinates-edit").replaceWith("<div id='subordinates-edit'></div>");
                if (Foris.subordinatesGetView() == "subordinates") {
                    $(".subordinate-buttons button").show('slow');
                    await $(".subordinate-buttons button").promise();
                }
            });
        };
        Foris.subordinateInEditMode = false;
        Foris.subordinatesAlive = {};
        Foris.subordinateKeepAliveTimeouts = {};
        Foris.subordinateSetKeepAliveTimeout = (controller_id) => {
            let element = $(`#sub-${controller_id}`);
            let state_element = element.find(".state");
            Foris.subordinateKeepAliveTimeouts[controller_id] = setTimeout(() => {
                Foris.subordinatesAlive[controller_id] = false;
                state_element.removeClass();
                state_element.addClass("state fas fa-exclamation-circle");
                delete Foris.subordinateKeepAliveTimeouts[controller_id];
                $(`div[data-controller-id=${controller_id}]`).replaceWith("<div id='subordinates-edit'>Chyba</div>");
            }, 3000);
        };
        Foris.updateSubordinateState = async (data) => {
            let element = $(`#sub-${data.id}`);
            let state_element = element.find(".state");
            if (!document.hidden) {
                await state_element.animate({opacity: '0.2'}, 50);
            }
            state_element.removeClass();
            switch (data.state) {
                case 'started':
                    state_element.addClass("state fas fa-circle");
                    break;
                case 'running':
                    if (data.id in Foris.subordinateKeepAliveTimeouts) {
                        clearTimeout(Foris.subordinateKeepAliveTimeouts[data.id]);
                    }
                    state_element.addClass("state fas fa-check-circle");
                    Foris.subordinateSetKeepAliveTimeout(data.id);
                    if (!Foris.subordinatesAlive[data.id]) {  // query backend if needed
                        Foris.queryBackendWifi(data.id);
                    }
                    Foris.subordinatesAlive[data.id] = true;
                    if (!Foris.subordinateInEditMode) {
                        $(`#sub-${data.id}`).find("button[value=edit]").show("slow");
                    }
                    break;
                case 'exitted':
                    state_element.addClass("state fas fa-exclamation-circle");
                    break;
                default:
                    state_element.addClass("state fas fa-question-circle");
                    break;
            }
            if (!document.hidden) {
                await state_element.animate({opacity: '1.0'}, 50);
            }
        };
        Foris.addWsHanlder("subordinates", async (msg) => {
            switch(msg.action) {
              case "add_sub":
              case "add_subsub":
              case "del":
              case "set_enabled":
                await Foris.loadSubordinatesList();
                break;
            }
        });
        Foris.addWsHanlder("remote", async (msg) => {
            switch(msg.action) {
                case "advertize":
                    Foris.updateSubordinateState(msg.data);
                    break;
            };
        }, '+');
        $(document).ready(function() {
            Foris.loadSubordinatesList();
            Foris.afterAjaxUpdateFunctions.push(Foris.suboridnatesOverrideEditClose);
            Foris.afterAjaxUpdateFunctions.push(Foris.overrideSubordinatesEditButton);
        });
    </script>
    <style>
    #subordinates-table .sub-line .state {
        font-size: 1.5rem;
    };
    #subordinates-table td {
        vertical-align: top;
    };
    </style>
</div>
{% endif %}
{% endblock %}
