<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/api_tester_layout}">
<body>

<section layout:fragment="contentFragment">
    <script>
        require.config({paths: {'vs': '/plugins/vs'}});
    </script>
    <div id="loading-overlay" style="display: none;">
        <div class="d-flex justify-content-center align-items-center"
             style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 9999;">
            <div class="text-center">
                <span class="sr-only">Loading...</span>
                <br/>
                <button id="cancel-ajax" class="btn btn-danger mt-3">Cancel</button>
            </div>
        </div>
    </div>
    <div class="container">
        <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
        <ul class="nav nav-tabs" role="tablist" id="apiRequestTabTitle">
        </ul>
        <div class="tab-content" id="apiRequestTabContent">
        </div>
    </div>
    <div class="modal fade" id="new_api_request_modal" tabindex="-1" aria-labelledby="new_api_request_modal"
         aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">새로운 API 추가</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <select class="form-select" id="modal_collection"></select>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
                    <button type="button" class="btn btn-primary add_new_request">추가</button>
                </div>
            </div>
        </div>
    </div>
    <div id="apiRequestTemplate" style="display: none;">
        <div class="tab-pane fade mt-1">
            <div><span class="collection_name"></span> &gt; <span class="api_name"></span></div>
            <div class="d-flex align-items-center">
                <div class="form-floating col-md-1 me-1">
                    <select name="method" class="form-select method">
                        <option value="POST">POST</option>
                        <option value="GET">GET</option>
                        <option value="PUT">PUT</option>
                        <option value="DELETE">DELETE</option>
                        <option value="CONNECT">CONNECT</option>
                        <option value="HEAD">HEAD</option>
                        <option value="OPTIONS">OPTIONS</option>
                        <option value="TRACE">TRACE</option>
                        <option value="PATCH">PATCH</option>
                    </select>
                    <label class="form-label must">Method</label>
                </div>
                <div class="form-floating col-md-1 me-1">
                    <select class="form-select server" name="server" required>
                        <option th:each="server : ${servers}" th:value="${server.id}" th:text="${server.name}" th:data-path="${server.basePath}"></option>
                    </select>
                    <label class="form-label must">Server</label>
                </div>
                <div class="form-floating col-md-1 me-1">
                    <div class="form-floating col-md">
                        <input type="text" name="basePath" class="form-control" readonly>
                        <label class="must">base path</label>
                    </div>
                </div>
                <div class="input-group col-md me-1">
                    <div class="form-floating col-md">
                        <input type="text" name="path" class="form-control path" placeholder="호출할 경로 (/부터 입력)"
                               required>
                        <label class="must">Path</label>
                    </div>
                    <button class="btn btn-primary send">Send</button>
                </div>
                <button class="btn btn-primary save" style="height: 58px;">저장</button>
            </div>
            <ul class="nav nav-tabs mt-1" role="tablist">
                <li class="nav-item" role="presentation">
                    <button class="nav-link btn_request_body_tab" data-bs-toggle="tab"
                            type="button" role="tab" aria-controls="requestBody"
                            aria-selected="false">Body
                    </button>
                </li>
                <li class="nav-item" role="presentation">
                    <button class="nav-link btn_request_param_tab" data-bs-toggle="tab"
                            type="button" role="tab" aria-controls="paramTab"
                            aria-selected="true">Param
                    </button>
                </li>
                <li class="nav-item" role="presentation">
                    <button class="nav-link btn_request_header_tab" data-bs-toggle="tab"
                            type="button" role="tab" aria-controls="requestHeader"
                            aria-selected="false">Header
                    </button>
                </li>
            </ul>
            <div class="tab-content border-bottom" style="min-height: 300px;">
                <div class="tab-pane fade show request_param_tab" role="tabpanel"
                     aria-labelledby="requestParams-tab">
                    <table class="table">
                        <thead>
                        <tr>
                            <th scope="col">#</th>
                            <th scope="col">이름</th>
                            <th>값</th>
                            <th>
                                <button type="button" class="btn btn-secondary btn-sm btn_add_query">추가
                                </button>
                            </th>
                        </tr>
                        </thead>
                        <tbody class="query_params">
                        </tbody>
                    </table>
                </div>
                <div class="tab-pane fade request_header_tab" role="tabpanel"
                     aria-labelledby="requestHeader-tab">
                    <table class="table">
                        <thead>
                        <tr>
                            <th scope="col">#</th>
                            <th scope="col">이름</th>
                            <th scope="col">값</th>
                            <th scope="col">
                                <button type="button" class="btn btn-secondary btn-sm btn_add_header">추가
                                </button>
                            </th>
                        </tr>
                        </thead>
                        <tbody class="request_headers">
                        </tbody>
                    </table>
                </div>
                <div class="tab-pane fade request_body_tab" role="tabpanel"
                     aria-labelledby="requestBody-tab">
                    <select class="form-select mt-1 request_body_type" name="request_type">
                        <option value="json">json</option>
                        <option value="xml">xml</option>
                        <option value="text/plain">text/plain</option>
                    </select>
                    <div class="request_body mt-1" style="width:100%;height:250px;border:1px solid grey;"></div>
                </div>
            </div>
            <div class="mt-1">
                <span>Response</span>
                <span class="response_status"></span>
                <span class="response_time"></span>
                <span class="response_size"></span>
            </div>
            <ul class="nav nav-tabs mt-1" role="tablist">
                <li class="nav-item" role="presentation">
                    <button class="nav-link active" data-bs-toggle="tab"
                            data-bs-target="#responseBodyTab" type="button" role="tab" aria-controls="responseBody"
                            aria-selected="false">Body
                    </button>
                </li>
                <li class="nav-item" role="presentation">
                    <button class="nav-link" data-bs-toggle="tab"
                            data-bs-target="#responseHeaderTab" type="button" role="tab"
                            aria-controls="responseHeader"
                            aria-selected="false">Header
                    </button>
                </li>
            </ul>
            <div class="tab-content border-bottom" style="min-height: 250px;">
                <div class="tab-pane fade show active" id="responseBodyTab" role="tabpanel"
                     aria-labelledby="requestParams-tab">
                    <div class="response_body mt-1" style="width:100%;height:250px;border:1px solid grey;"></div>
                </div>
                <div class="tab-pane fade" id="responseHeaderTab" role="tabpanel"
                     aria-labelledby="requestParams-tab">
                    <table class="table">
                        <thead>
                        <tr>
                            <th scope="col">이름</th>
                            <th scope="col">값</th>
                        </tr>
                        </thead>
                        <tbody class="response_headers">
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
    <div id="inputTemplate" style="display: none;">
        <table>
            <tbody>
            <tr>
                <td>
                    <div class="form-check">
                        <input class="form-check-input" type="checkbox" name="enabled"/>
                    </div>
                </td>
                <td>
                    <input class="form-control" type="text" name="key"/>
                </td>
                <td>
                    <input class="form-control" type="text" name="value"/>
                </td>
                <td>
                    <button type="button" class="btn btn-secondary btn-sm btn_remove">제거</button>
                </td>
            </tr>
            </tbody>
        </table>
    </div>
    <div id="responseHeaderTemplate" style="display: none;">
        <table>
            <tbody>
            <tr>
                <td>
                    <input class="form-control" type="text" name="key" readonly/>
                </td>
                <td>
                    <input class="form-control" type="text" name="value" readonly/>
                </td>
            </tr>
            </tbody>
        </table>
    </div>
    <ul id="collectionTemplate" style="display: none;">
        <li>
            <div class="d-flex justify-content-between">
                <button class="btn d-inline-flex align-items-center rounded new_collection normal"
                        data-bs-toggle="collapse"
                        data-bs-target="" aria-expanded="false" aria-current="false">컬렉션
                </button>
                <div class="d-flex justify-content-between">
                    <button class="p-1 reset-button edit_collection"><i class="fa fa-sharp fa-file-edit"></i></button>
                    <button class="p-1 reset-button delete_collection"><i class="fa fa-sharp fa-trash-can"></i></button>
                </div>
            </div>
            <div class="collapse">
                <ul class="list-unstyled fw-normal pb-1 small">
                </ul>
            </div>
        </li>
    </ul>
    <ul id="collectionApiTemplate" style="display: none;">
        <li class="d-flex justify-content-between">
            <a href="#" class="d-inline-flex align-items-center rounded"></a>
            <div class="d-flex justify-content-between">
                <button class="p-1 reset-button edit_api_request"><i class="fa fa-sharp fa-file-edit"></i></button>
                <button class="p-1 reset-button delete_api_request"><i class="fa fa-trash-can"></i></button>
            </div>

        </li>
    </ul>
</section>
</body>

<th:block layout:fragment="contentScript">
    <script>
        $(function () {

            let apiRequests = [];
            let collections = [];

            let view = {
                currentIdx: 0,
                responses: [],
                requests: [],
                init: function () {

                    $('#filter_text').on('input', function(){
                       view.renderCollections();
                    });
                    $("#cancel-ajax").on("click", function () {
                        if (controller.currentAjaxRequest) {
                            controller.currentAjaxRequest.abort();
                            controller.hideLoadingOverlay();
                        }
                    });

                    $('#new_request').on('click', function () {
                        if (collections.length == 0) {
                            alert('새로운 컬렉션을 추가해 주세요.');
                            return;
                        }
                        $('#new_api_request_modal').modal('show');
                    });

                    $('#new_api_request_modal').find('.add_new_request').on('click', function () {
                        controller.addAPIRequest($('#new_api_request_modal').find('select').val());
                    });

                    $('#new_collection_modal').find('.save').on('click', function () {
                        controller.addCollection($('#new_collection_modal').find('input').val());
                    });

                    $('#confirm_delete_modal').find('button.confirm_delete').on('click', function () {
                        controller.removeCollection($(this).data('id'));
                    });

                    $('#confirm_delete_api_modal').find('button.confirm_delete_api').on('click', function () {
                        controller.deleteApiRequest($(this).data('collection'), $(this).data('id'));
                    });

                    controller.loadCollections();
                },
                renderParam: function (tabIdx) {
                    let target = $('#api_request_' + tabIdx);
                    target.find('.query_params').empty();

                    let model = apiRequests[tabIdx];
                    for (let i = 0; i < model.queryParams.length; i++) {
                        let template = $('#inputTemplate').children().find('tr').clone();
                        template.find('input[name="key"]').val(model.queryParams[i].key);
                        template.find('input[name="value"]').val(model.queryParams[i].value);

                        if (model.queryParams[i].enabled) {
                            template.find('input[name="enabled"]').prop("checked", model.queryParams[i].enabled);
                        }

                        template.find('button').attr("data-id", i);

                        template.find('input[name="enabled"]').on('change', function () {
                            model.queryParams[i].enabled = $(this).prop('checked');
                            controller.buildPath(tabIdx);
                        });
                        template.find('input[name="key"]').on('focusout', function () {
                            model.queryParams[i].key = $(this).val();
                            controller.buildPath(tabIdx);
                        });
                        template.find('input[name="value"]').on('focusout', function () {
                            model.queryParams[i].value = $(this).val();
                            controller.buildPath(tabIdx);
                        });

                        target.find('.query_params').append(template);
                    }

                    target.find('.path').val(model.path);

                },
                renderHeaders: function (tabIdx) {
                    let target = $('#api_request_' + tabIdx);
                    target.find('.request_headers').empty();

                    let model = apiRequests[tabIdx];
                    for (let i = 0; i < model.headers.length; i++) {
                        let template = $('#inputTemplate').children().find('tr').clone();
                        if (model.headers[i].enabled) {
                            template.find('input[name="enabled"]').prop("checked", model.headers[i].enabled);
                        }
                        template.find('input[name="key"]').val(model.headers[i].key);
                        template.find('input[name="value"]').val(model.headers[i].value);
                        template.find('button').attr("data-id", i);

                        template.find('input[name="enabled"]').on('change', function () {
                            model.headers[i].enabled = $(this).prop('checked');
                        });
                        template.find('input[name="key"]').on('input', function () {
                            model.headers[i].key = $(this).val();
                        });
                        template.find('input[name="value"]').on('input', function () {
                            model.headers[i].value = $(this).val();
                        });

                        target.find('.request_headers').append(template);
                    }
                },
                renderTabHeader: function () {
                    let apiRequestTabTitle = $('#apiRequestTabTitle');
                    apiRequestTabTitle.empty();
                    for (let idx = 0; idx < apiRequests.length; idx++) {
                        let $span = $('<span>')
                            .html(' <i class="fa fa-light fa-close" data-id="' + idx + '"></i>');

                        $span.on('click', function (event) {
                            event.stopPropagation();
                            controller.closeTab(idx);
                        });

                        let tabButton = $('<button>').attr('class', 'nav-link')
                            .attr('data-bs-toggle', 'tab')
                            .attr('type', 'button')
                            .attr('data-bs-target', '#api_request_' + idx)
                            .attr('role', 'tab')
                            .attr('aria-controls', 'api_request_' + idx)
                            .attr('aria-selected', 'false')
                            .text(apiRequests[idx].name);
                        tabButton.append($span);

                        let li = $('<li>').attr('class', 'nav-item')
                            .attr('role', 'presentation')
                            .append(tabButton);

                        apiRequestTabTitle.append(li);
                    }
                },
                openTab: function(idx){
                    $('#apiRequestTabTitle li:eq(' + idx + ') button').tab('show');
                    $('#api_request_'+ idx+' li:eq(0) button').tab('show')
                },
                renderTabContent: function (idx) {
                    let apiRequestTabContent = $('#apiRequestTabContent');

                    let model = apiRequests[idx];

                    let template = $('#apiRequestTemplate').children().clone();

                    template.attr('id', 'api_request_' + idx);
                    template.attr("data-id", idx);
                    template.attr('class', 'tab-pane fade mt-1' + (idx === this.currentIdx ? ' show active' : ''));
                    template.find('.btn_request_param_tab').attr('data-bs-target', "#requestParamTab_" + idx);
                    template.find('.btn_request_header_tab').attr('data-bs-target', "#requestHeaderTab_" + idx);
                    template.find('.btn_request_body_tab').attr('data-bs-target', "#requestBodyTab_" + idx);

                    template.find('.request_header_tab').attr('id', "requestHeaderTab_" + idx);
                    template.find('.request_param_tab').attr('id', "requestParamTab_" + idx);
                    template.find('.request_body_tab').attr('id', "requestBodyTab_" + idx);
                    template.find('.api_name').text(model.name);
                    template.find('.collection_name').text(model.collectionName);

                    apiRequestTabContent.append(template);
                    let target = $('#api_request_' + idx);

                    target.find('.btn_add_header').click(function () {
                        controller.addHeader(idx);
                    });
                    target.find('.btn_add_query').click(function () {
                        controller.addQueryParam(idx, '', '');
                    });

                    target.find('input[name="basePath"]').val(target.find('select[name="server"] option:selected').data('path'));
                    target.find('select[name="server"]').val(model.server);
                    target.find('select[name="server"]').on('change', function () {
                        model.server = $(this).val();
                        let selected = $(this).find('option:selected');
                        target.find('input[name="basePath"]').val(selected.data('path'));
                    });

                    target.find('.method').on('change', function () {
                        model.method = $(this).val();
                    });

                    target.find('.request_headers').on('click', 'button', function () {
                        if ($(this).hasClass('btn_remove')) {
                            controller.removeHeader(idx, $(this).data("id"));
                        }
                    });

                    target.find('.query_params').on('click', 'button', function () {
                        if ($(this).hasClass('btn_remove')) {
                            controller.removeQueryParam(idx, $(this).data("id"));
                        }
                    });

                    target.find('.path').on('input', function () {
                        model.path = $(this).val();
                        model.queryParams = [];
                        let queryString = model.path.split('?')[1];
                        if (queryString) {
                            let queryParamArray = queryString.split('&');
                            for (let i = 0; i < queryParamArray.length; i++) {
                                let queryParam = queryParamArray[i].split('=');
                                controller.addQueryParam(idx, queryParam[0], queryParam[1] === undefined ? '' : queryParam[1]);
                            }
                        }
                    });

                    target.find('.send').click(function () {
                        controller.send(idx);
                    });
                    target.find('.save').attr('data-collection', ); //TODO
                    target.find('.save').click(function(){
                        controller.saveAPIRequest(apiRequests[idx]);
                    });

                    let me = this;

                    require(['vs/editor/editor.main'], function () {
                        let requestBodyEditor = monaco.editor.create(target.find(".request_body")[0], {
                            value: model.requestBody,
                            language: 'json',
                            theme: 'vs-light',
                            automaticLayout: true
                        });
                        me.requests.push(requestBodyEditor);
                        target.find(".request_body")[0].addEventListener('shown.bs.tab', function () {
                            me.requests[idx].layout();
                        });

                        me.requests[idx].onDidChangeModelContent(function (e) {
                            model.requestBody = requestBodyEditor.getValue();
                        });

                        target.find('.request_body_type').on('change', function () {
                            let model = requestBodyEditor.getModel();
                            monaco.editor.setModelLanguage(model, $(this).val());
                        });

                        let responseBodyEditor = monaco.editor.create(target.find(".response_body")[0], {
                            value: '',
                            language: 'json',
                            theme: 'vs-light',
                            automaticLayout: true
                        });
                        me.responses.push(responseBodyEditor);
                    });

                    target.find('.path').val(model.path);
                    target.find('.method').val(model.method);
                    this.renderParam(idx);
                    this.renderHeaders(idx);
                    this.openTab(view.currentIdx);
                },
                render: function () {
                    let apiRequestTabContent = $('#apiRequestTabContent');
                    let apiRequestTabTitle = $('#apiRequestTabTitle');
                    apiRequestTabTitle.empty();
                    apiRequestTabContent.empty();

                    this.responses = [];

                    this.renderTabHeader();
                    for (let idx = 0; idx < apiRequests.length; idx++) {
                        this.renderTabContent(idx);
                    }
                },
                renderResponse: function (tabIdx) {
                    let model = apiRequests[tabIdx];
                    let target = $('#api_request_' + tabIdx);
                    target.find('.response_headers').empty();
                    target.find(".response_status").empty();

                    try {
                        const parsedJson = JSON.parse(model.responseModel.body);
                        const formattedJson = JSON.stringify(parsedJson, null, 2);
                        this.responses[tabIdx].setValue(formattedJson);
                    } catch(e) {
                        this.responses[tabIdx].setValue(model.responseModel.body);
                    }
                    for (let i = 0; i < model.responseModel.headers.length; i++) {
                        let template = $('#responseHeaderTemplate').children().find('tr').clone();
                        template.find('input[name="key"]').val(model.responseModel.headers[i].key);
                        template.find('input[name="value"]').val(model.responseModel.headers[i].value);
                        target.find('.response_headers').append(template);
                    }

                    target.find(".response_status").text("status: " + model.responseModel.status);
                    target.find(".response_time").text("time: " + model.responseModel.time + "ms");
                    target.find(".response_size").text("size: " + model.responseModel.size + "bytes");
                },
                renderCollections: function () {
                    let select = $('#modal_collection');
                    let sidemenu = $('#side_menubar');
                    select.empty();
                    sidemenu.empty();

                    for (let i = 0; i < collections.length; i++) {

                        let template = $('#collectionTemplate').children().clone();
                        template.attr('id', 'collection_' + i);
                        template.find('button.new_collection').text(collections[i].name);
                        template.find('button.new_collection').attr('data-bs-target', '#btn_collection_' + i);
                        template.find('button.delete_collection').attr('data-id', collections[i].id);
                        template.find('button.delete_collection').on('click', function () {
                            $('#confirm_delete_modal').find('.confirm_delete').attr('data-id', $(this).data('id'));
                            $('#confirm_delete_modal').modal('show');
                        });

                        let editCollectionBtn = template.find('button.edit_collection');
                        editCollectionBtn.on('click', function () {
                            let saveBtn = $('#edit_name_modal').find('button.change_name');
                            saveBtn.on('click', function(){
                                collections[i].name = $('#edit_name_modal').find('input').val();
                                controller.saveCollection(collections[i].id, collections[i].name);
                                view.renderCollections();
                                $('#edit_name_modal').modal('hide');
                            });
                            $('#edit_name_modal').find('input').val('');
                            $('#edit_name_modal').modal('show');
                        });

                        template.find('.collapse').attr('id', 'btn_collection_' + i);

                        for (let j = 0; j < collections[i].apis.length; j++) {

                            let collectionApiTemplate = $('#collectionApiTemplate').children().clone();
                            let link = collectionApiTemplate.find('a');
                            let btn = collectionApiTemplate.find('button.delete_api_request');
                            link.text(collections[i].apis[j].name);
                            link.attr('data-collection', collections[i].id);
                            link.attr('data-id', collections[i].apis[j].id);
                            link.on('click', function () {
                                controller.openApiRequest($(this).data('collection'), $(this).data('id'));
                            })
                            btn.attr('data-collection', collections[i].id);
                            btn.attr('data-id', collections[i].apis[j].id);
                            btn.on('click', function () {
                                $('#confirm_delete_api_modal').find('.confirm_delete_api').attr('data-id', $(this).data('id'));
                                $('#confirm_delete_api_modal').find('.confirm_delete_api').attr('data-collection', $(this).data('collection'));
                                $('#confirm_delete_api_modal').modal('show');
                            });

                            let editBtn = collectionApiTemplate.find('button.edit_api_request');
                            editBtn.on('click', function () {
                                let saveBtn = $('#edit_name_modal').find('button.change_name');
                                saveBtn.on('click', function(){
                                    collections[i].apis[j].name = $('#edit_name_modal').find('input').val();
                                    controller.saveAPIRequest(collections[i].apis[j]);
                                    view.renderCollections();
                                    $('#edit_name_modal').modal('hide');
                                });
                                $('#edit_name_modal').find('input').val('');
                                $('#edit_name_modal').modal('show');
                            });

                            template.find('.collapse ul').append(collectionApiTemplate);
                        }

                        let option = $('<option>');
                        option.attr('value', collections[i].id);
                        option.text(collections[i].name);

                        select.append(option);
                        sidemenu.append(template);
                    }
                }
            }

            let controller = {
                currentAjaxRequest: null,
                init: function () {
                    view.init();
                },
                addHeader: function (tabIdx) {
                    let model = apiRequests[tabIdx];
                    model.headers.push({
                        enabled: true,
                        key: '',
                        value: ''
                    });
                    view.renderHeaders(tabIdx);
                },
                removeHeader: function (tabIdx, idx) {
                    let model = apiRequests[tabIdx];
                    model.headers.splice(idx, 1);
                    view.renderHeaders(tabIdx);
                },
                addQueryParam: function (tabIdx, key, value) {
                    let model = apiRequests[tabIdx];
                    model.queryParams.push({
                        enabled: true,
                        key: key,
                        value: value
                    });
                    view.renderParam(tabIdx);
                },
                buildPath: function (tabIdx) {
                    let model = apiRequests[tabIdx];
                    let queryString = model.path.split('?')[0];
                    if (model.queryParams.length > 0) {
                        queryString += '?';
                    }
                    for (let i = 0; i < model.queryParams.length; i++) {
                        if (!model.queryParams[i].enabled) {
                            continue;
                        }
                        queryString += model.queryParams[i].key + '=' + model.queryParams[i].value;
                        if (i < model.queryParams.length - 1) {
                            queryString += '&';
                        }
                    }
                    model.path = queryString;
                    view.renderParam(tabIdx);
                },
                removeQueryParam: function (tabIdx, idx) {
                    let model = apiRequests[tabIdx];
                    model.queryParams.splice(idx, 1);
                    this.buildPath(tabIdx);
                    view.renderParam(tabIdx);
                },
                showLoadingOverlay: function () {
                    $("#loading-overlay").show();
                },
                hideLoadingOverlay: function () {
                    $("#loading-overlay").hide();
                },
                send: function (tabIdx) {
                    let model = apiRequests[tabIdx];
                    let target = $('#api_request_' + tabIdx);
                    target.find('.response_headers').empty();
                    view.responses[tabIdx].setValue('');
                    let startTime = new Date().getTime();

                    if (model.path !== '') {
                        controller.showLoadingOverlay();
                        this.currentAjaxRequest = $.ajax({
                            url: '/mgmt/api/test.do',
                            type: 'POST',
                            contentType: 'application/json',
                            data: JSON.stringify(model),
                            success: function (data) {
                                model.responseModel.status = data.status;
                                model.responseModel.body = data.body;
                                model.responseModel.headers = data.headers;
                                model.responseModel.size = data.size;
                            },
                            error: function (response, textStatus, errorThrown) {
                                controller.hideLoadingOverlay();
                            },
                            complete: function () {
                                let endTime = new Date().getTime();
                                model.responseModel.time = endTime - startTime;
                                view.renderResponse(tabIdx);
                                controller.hideLoadingOverlay();
                            }
                        });
                    }
                },
                loadCollections: function () {
                    controller.showLoadingOverlay();
                    this.currentAjaxRequest = $.ajax({
                        url: '/mgmt/collections/list.do',
                        type: 'GET',
                        contentType: 'application/json',
                        success: function (data) {
                            collections = data;
                            for (let i = 0; i < collections.length; i++) {
                                if(collections[i].apis !== undefined){
                                    for (let j = 0; j< collections[i].apis.length; j++) {
                                        collections[i].apis[j].collectionId = collections[i].id;
                                    }
                                }
                            }
                        },
                        error: function (response, textStatus, errorThrown) {
                            controller.hideLoadingOverlay();
                        },
                        complete: function () {
                            view.renderCollections();
                            controller.hideLoadingOverlay();
                        }
                    });
                },
                addCollection: function (name) {
                    controller.showLoadingOverlay();
                    this.currentAjaxRequest = $.ajax({
                        url: '/mgmt/collections/create.do',
                        type: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify({name: name}),
                        success: function (data) {

                        },
                        error: function (response, textStatus, errorThrown) {
                            controller.hideLoadingOverlay();
                        },
                        complete: function () {
                            controller.loadCollections();
                            controller.hideLoadingOverlay();
                            $('#new_collection_modal').modal('hide');
                        }
                    });
                },
                saveCollection: function(id, name){
                    controller.showLoadingOverlay();
                    this.currentAjaxRequest = $.ajax({
                        url: '/mgmt/collections/update.do',
                        type: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify({id: id, name: name}),
                        success: function (data) {

                        },
                        error: function (response, textStatus, errorThrown) {
                            controller.hideLoadingOverlay();
                        },
                        complete: function () {
                            controller.loadCollections();
                            controller.hideLoadingOverlay();
                            $('#new_collection_modal').modal('hide');
                        }
                    });
                },
                removeCollection: function (id) {
                    controller.showLoadingOverlay();
                    this.currentAjaxRequest = $.ajax({
                        url: '/mgmt/collections/delete.do',
                        type: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify({id: id}),
                        success: function () {
                        },
                        error: function (response, textStatus, errorThrown) {
                            let error = response.responseJSON;
                            controller.hideLoadingOverlay();
                            alert(error.error);
                        },
                        complete: function () {
                            controller.loadCollections();
                            controller.hideLoadingOverlay();
                            $('#confirm_delete_modal').modal('hide');
                        }
                    });
                },
                saveAPIRequest: function(model){
                    this.currentAjaxRequest = $.ajax({
                        url: '/mgmt/collections/{collectionId}/apis/save.do'.replace('{collectionId}', model.collectionId),
                        type: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify(model),
                        success: function (data) {
                        },
                        error: function (response, textStatus, errorThrown) {
                            controller.hideLoadingOverlay();
                        },
                        complete: function () {
                            controller.hideLoadingOverlay();
                        }
                    });
                },
                addAPIRequest: function (collectionId) {

                    let name = 'New Request';
                    let newApi = {
                        id: '',
                        server: null,
                        method: 'GET',
                        name: name,
                        path: '',
                        headers: [],
                        queryParams: [],
                        requestBody: '',
                        collectionId : collectionId,
                        responseModel: {
                            status: 0,
                            time: 0,
                            size: 0,
                            headers: [],
                            body: ''
                        }
                    };

                    this.currentAjaxRequest = $.ajax({
                        url: '/mgmt/collections/{collectionId}/apis/save.do'.replace('{collectionId}', collectionId),
                        type: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify(newApi),
                        success: function (data) {
                            newApi.id = data;
                        },
                        error: function (response, textStatus, errorThrown) {
                            controller.hideLoadingOverlay();
                        },
                        complete: function () {
                            controller.loadCollections();
                            apiRequests.push(newApi);
                            view.currentIdx = apiRequests.length - 1;

                            view.renderTabHeader();
                            view.renderTabContent(view.currentIdx);

                            controller.hideLoadingOverlay();
                            $('#new_api_request_modal').modal('hide');
                        }
                    });
                },
                openApiRequest: function (collectionId, apiId) {
                    let collectionName = collections.filter(function (collection) {
                        return collection.id === collectionId;
                    })[0].name;
                    let selectedApi = collections.filter(function (collection) {
                        return collection.id === collectionId;
                    })[0].apis.filter(function (api) {
                        return api.id === apiId;
                    })[0];

                    if (selectedApi !== undefined) {
                        selectedApi.collectionName = collectionName;
                        let tab = apiRequests.filter(function (api) {
                            return api.id === selectedApi.id;
                        })[0];

                        if (selectedApi.responseModel === undefined) {
                            selectedApi.responseModel = {
                                status: 0,
                                time: 0,
                                size: 0,
                                headers: [],
                                body: ''
                            };
                        }

                        if (tab === undefined) {
                            apiRequests.push(selectedApi);
                            view.currentIdx = apiRequests.length - 1;
                            view.renderTabHeader();
                            view.renderTabContent(view.currentIdx);
                        } else {
                            //show selected tab
                            view.currentIdx = apiRequests.findIndex(function (api) {
                                return api.id === selectedApi.id;
                            });

                            view.openTab(view.currentIdx);
                        }
                    }
                },
                deleteApiRequest: function (collectionId, apiId) {
                    this.currentAjaxRequest = $.ajax({
                        url: '/mgmt/collections/{id}/apis/delete.do'.replace('{id}', collectionId),
                        type: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify({id: apiId}),
                        success: function (data) {
                        },
                        error: function (response, textStatus, errorThrown) {
                            controller.hideLoadingOverlay();
                        },
                        complete: function () {
                            controller.hideLoadingOverlay();

                            //get the api with apiIdx index from apiRequests
                            let apiIdx = apiRequests.findIndex(function (api) {
                                return api.id === apiId;
                            });
                            controller.closeTab(apiIdx);
                            controller.loadCollections();
                            $('#confirm_delete_api_modal').modal('hide');
                        }
                    });
                },
                closeTab: function (idx) {
                    apiRequests.splice(idx, 1);
                    view.render();
                    $('#apiRequestTabTitle li:eq(0) button').tab('show');
                }
            }

            controller.init();

        });
    </script>
</th:block>
</html>

