{#
/*
 * Xibo - Digital Signage - http://www.xibo.org.uk
 * Copyright (C) 2022 Xibo Signage Ltd
 *
 * This file is part of Xibo.
 *
 * Xibo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * Xibo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Xibo.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#}

{% extends "authed.twig" %}
{% import "inline.twig" as inline %}

{% block title %}{% trans "Report: Display Played Percentage" %} | {% endblock %}

{% block actionMenu %}
    {% include "report-schedule-buttons.twig" %}
{% endblock %}

{% block pageContent %}

    <div class="widget">
        <div class="widget-title">
            <span>{% trans "Display Played Percentage" %}</span>
        </div>

        {% include "report-selector.twig" %}

        <div class="widget-body">
            <div class="XiboGrid" id="{{ random() }}" data-grid-name="displayPercentageView" data-refresh-on-form-submit="false">
                <div class="XiboFilterCustom card bg-light mb-3">
                    <div class="FilterDiv card-body" id="displayPercentageReport">
                        <!-- Form Filter -->
                        <form class="form-inline">
                            {# Campaign list only. #}
                            {% set attributes = [
                                { name: "data-search-url", value:  url_for("campaign.search") },
                                { name: "data-width", value: "200px" },
                                { name: "data-allow-clear", value: "true" },
                                { name: "data-placeholder--id", value: null },
                                { name: "data-placeholder--value", value: "" },
                            ] %}

                            {% set title %}{% trans "Campaign" %} * {% endset %}
                            {% set helpText %}{% trans "Please select a Campaign" %}{% endset %}
                            {{ inline.dropdown("parentCampaignId", "single", title, "", null, "campaignId", "campaign", "", "", "", "", "", attributes) }}

                            <div class="w-100">
                                <a id="applyBtn" class="btn btn-success">
                                    <span>{% trans "Apply" %}</span>
                                </a>
                            </div>
                        </form>
                    </div>
                </div>

                <!-- Card Header -->
                <div class="card-header">
                    <ul class="nav nav-tabs card-header-tabs" role="tablist">
                        <li class="nav-item">
                            <a class="nav-link active" id="tabular-tab" data-toggle="tab" href="#tabularTab" role="tab"
                               aria-controls="tabularTab" aria-selected="true">Tabular</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" id="spend-chart-tab" data-toggle="tab" href="#spendChartTab" role="tab"
                               aria-controls="chartTab" aria-selected="false">Chart (Spend)</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" id="playtime-chart-tab" data-toggle="tab" href="#playtimeChartTab" role="tab"
                               aria-controls="chartTab" aria-selected="false">Chart (Playtime)</a>
                        </li>
                    </ul>
                </div>

                <!-- Card Body -->
                <div class="card-body">
                    <div class="tab-content">

                        <!-- TABULAR TAB-->
                        <div class="tab-pane active" id="tabularTab" role="tabpanel" aria-labelledby="tabular-tab">
                            <!-- DATATABLE -->
                            <div class="table-container" id="table_wrapper">
                                <table id="displayPercentageTbl"
                                       class="table xibo-table table-striped table-full-width"
                                       style="width: 100%"
                                       data-state-preference-name="displayPercentageGrid"
                                       data-url="/report/data/displayPercentage">
                                    <thead>
                                    <tr>
                                        <th>{% trans "Display" %}</th>
                                        <th>{% trans "Spend(%)" %}</th>
                                        <th>{% trans "Playtime(%)" %}</th>
                                    </tr>
                                    </thead>
                                    <tbody>

                                    </tbody>
                                    <tfoot>
                                    <tr>
                                        <th></th>
                                        <th></th>
                                        <th></th>
                                    </tr>
                                    </tfoot>
                                </table>
                            </div>
                        </div>

                        <!-- CHART TAB-->
                        <div class="tab-pane show" id="spendChartTab" role="tabpanel" aria-labelledby="spend-chart-tab">

                            <div id="otherSpend" style="position: absolute;">
                                <div class="switch-other-main">
                                    <input type="checkbox" id="otherSpendSwitch" checked
                                           data-chart-name="spendChart" data-chart-canvas="spendChartCanvas"
                                           data-on-text="Main" data-off-text="Other"/>
                                </div>
                            </div>
                            <div class="chart-container" style="height:550px;">
                                <canvas id="spendChartCanvas"
                                        {# style="clear:both; margin-top:25px;" height="70%"#}
                                ></canvas>
                            </div>
                        </div>

                        <!-- CHART TAB-->
                        <div class="tab-pane show" id="playtimeChartTab" role="tabpanel" aria-labelledby="playtime-chart-tab">

                            <div id="otherPlaytime" style="position: absolute;">
                                <div class="switch-other-main">
                                    <input type="checkbox" id="otherPlaytimeSwitch" checked
                                           data-chart-name="playtimeChart" data-chart-canvas="playtimeChartCanvas"
                                           data-on-text="Main" data-off-text="Other"/>
                                </div>
                            </div>
                            <div class="chart-container" style="height:550px;">
                                <canvas id="playtimeChartCanvas"
                                        {# style="clear:both; margin-top:25px;" height="70%"#}
                                ></canvas>
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

{% block javaScript %}

    <script type="text/javascript">

        $(document).ready(function() {

            let $report = $("#displayPercentageReport");
            let $dataTable = $('#displayPercentageTbl'); // Datatable

            // Charts
            let $spendChartCanvas = $('#spendChartCanvas');
            let $playtimeChartCanvas = $('#playtimeChartCanvas');

            let chart = null; // Chart
            let result; // XHR get data result

            let imageLoader = $("#imageLoader");
            let $warning = $("#applyWarning");
            let $applyBtn = $("#applyBtn");

            // Initialize table with empty data
            let table = $dataTable.DataTable({
                "language": dataTablesLanguage,
                dom: dataTablesTemplate,
                stateSave: true,
                stateDuration: 0,
                stateLoadCallback: dataTableStateLoadCallback,
                stateSaveCallback: dataTableStateSaveCallback,
                filter: false,
                order: [[1, "asc"]],
                data:{},
                "columns": [
                    {
                        data: 'label',
                        sortable: false
                    },
                    {
                        data: 'spendData',
                        sortable: false
                    },
                    {
                        data: 'playtimeDuration',
                        sortable: false
                    }
                ],
            });

            // Get Data
            function getData(url) {
                $.ajax({
                    url: url,
                    method: 'GET',
                    dataType: 'json',
                    data: $("#displayPercentageTbl").closest(".XiboGrid").find(".FilterDiv form").serializeObject(),
                    success: function success(data) {
                        result = data;
                        $applyBtn.removeClass('disabled');

                        // Based on tab load data
                        let activeTabHref = $('.nav-tabs .nav-item a.active').attr("href");
                        if (activeTabHref === '#spendChartTab') {
                            setSpendChartData($spendChartCanvas, result.table);
                        } else if (activeTabHref === '#playtimeChartTab') {
                            setPlaytimeChartData($playtimeChartCanvas, result.table);
                        } else {
                            setTabularData(table, result.table);
                        }

                        if (result.error) {
                            toastr.error(result.error);
                        }
                    },
                    error: function error(xhr, textStatus, _error) {
                        $applyBtn.removeClass('disabled');
                        toastr.error(xhr.responseJSON.message);
                    }
                });
            }

            function setTabularData(table, data) {
                table.clear().draw();

                if (Object.keys(data).length > 0) {
                    // Sort table by display spend
                    table.rows.add(data).order([1, 'desc']).draw()
                }
            }

            $('.switch-other-main').hide();

            function drawChart(chartData, configOptions, $ctx) {

                return new Chart($ctx, {
                    type: 'doughnut',
                    plugins: [ChartDataLabels],
                    data: chartData,
                    options: configOptions,
                });
            }

            function updateChartData(chartName, labels, chartData, bgColor) {
                eval(chartName).data.labels = labels;
                eval(chartName).data.datasets[0].data = chartData;
                eval(chartName).data.datasets[0].backgroundColor = bgColor;
                eval(chartName).update();
            }

            function updateConfigAsNewObject(chartName, total) {
                eval(chartName).options = {
                    plugins: {
                        legend: {
                            position: 'top'
                        },
                        datalabels: {
                            render: 'percentage',
                            fontColor: 'white',
                            precision: 2,
                        }
                    },
                    maintainAspectRatio: false,
                    animation: {
                        onComplete: function onComplete(animation) {
                            // hideLoading();
                        }
                    }
                };
                eval(chartName).update();
            }

            $("#otherSpendSwitch, #otherPlaytimeSwitch").bootstrapSwitch({
                onSwitchChange: function(e, state) {
                    let chartName = $(this).attr("data-chart-name");
                    let mainTotal = $(this).attr("data-main-total");

                    // Main Chart Info
                    let mainChartData = $(this).attr("data-main-data").split(",");
                    let mainLabels = $(this).attr("data-main-labels").split(",");
                    let mainBgColor = $(this).attr("data-main-bg-color").split(",");

                    // Other Chart Info
                    let otherChartData = $(this).attr("data-other-data").split(",");
                    let otherLabels = $(this).attr("data-other-labels").split(",");
                    let otherBgColor = $(this).attr("data-other-bg-color").split(",");

                    if (state) {
                        updateChartData(chartName, mainLabels, mainChartData, mainBgColor);
                    } else {
                        updateChartData(chartName, otherLabels, otherChartData, otherBgColor);
                    }

                    // Update chart config when other/main button pressed
                    updateConfigAsNewObject(chartName, mainTotal);
                }
            });


            // Set chart data
            let spendChart;
            function setSpendChartData($chartCanvas, response) {
                $('.chart-container .alert-info').remove();
                if (spendChart !== undefined && spendChart !== null) {
                    spendChart.destroy();
                }

                let mainChartTotal = 0;
                $.each(response, function (index, element) {
                    // Get total
                    mainChartTotal += element.spendData;
                });

                // Convert our data into a dataset we can use for this chart.
                let labels = [];
                let data = [];
                let backgroundColor = [];
                let sum = 0;

                let otherChartTotal = 0;
                let otherChartData = [];
                let otherChartLabels = [];
                let otherChartBgColor = [];
                $.each(response, function(index, element) {
                    let percent = 0;
                    percent = element.spendData / mainChartTotal * 100;

                    if (percent < 10) {
                        // Keep track of total of Other
                        otherChartTotal += element.spendData;
                        otherChartData.push(element.spendData);
                        otherChartLabels.push(element.label);
                        otherChartBgColor.push(element.backgroundColor);
                    } else {
                        labels.push(element.label);
                        data.push(element.spendData);
                        backgroundColor.push(element.backgroundColor);
                    }
                    sum += element.spendData;
                });

                if (sum <= 0) {
                    // Show a message
                    if ($('.chart-container .alert-info').length <= 0) {
                        $('.chart-container').append($('<div class="alert alert-info">No display data for Campaign.</div>'))
                    }
                    return;
                }

                let $otherSpendBtns = $('#otherSpend .switch-other-main');


                if (otherChartData.length === 1) {
                    // We push only on other slice in main chart
                    labels.push(otherChartLabels);
                    data.push(otherChartData);
                    backgroundColor.push(otherChartBgColor);
                } else if (otherChartData.length > 1) {
                    // We have other slice in chart
                    // Combine the Other slice in Main Chart
                    labels.push('Other');
                    data.push(otherChartTotal);

                    // Set background color of "Other Slice"
                    backgroundColor.push('#808080');

                    // Show two buttons Other and Main
                    $otherSpendBtns.show();
                }

                let chartData = {
                    labels: labels,
                    datasets: [
                        {
                            label: 'Display Played Percentage',
                            data: data,
                            backgroundColor: backgroundColor,
                        }],
                };
                let configOptions = {
                    plugins: {
                        legend: {
                            position: 'top',
                        },
                        datalabels: {
                            render: 'percentage',
                            fontColor: 'white',
                            precision: 2,
                        },
                    },
                    maintainAspectRatio: false,
                    animation: {
                        onComplete: function(animation) {
                            // hideLoading();
                        }
                    },
                };

                spendChart = drawChart(chartData, configOptions, $('#spendChartCanvas'));

                // Update chart config
                updateConfigAsNewObject('spendChart', mainChartTotal);

                $otherSpendBtns.find("input").attr("data-other-labels", otherChartLabels);
                $otherSpendBtns.find("input").attr("data-other-data", otherChartData);
                $otherSpendBtns.find("input").attr("data-other-bg-color", otherChartBgColor);

                $otherSpendBtns.find("input").attr("data-main-labels", labels);
                $otherSpendBtns.find("input").attr("data-main-data", data);
                $otherSpendBtns.find("input").attr("data-main-bg-color", backgroundColor);

                $otherSpendBtns.find("input").attr("data-main-total", mainChartTotal);

            }

            let playtimeChart;
            function setPlaytimeChartData($chartCanvas, response) {
                $('.chart-container .alert-info').remove();
                if (playtimeChart !== undefined && playtimeChart !== null) {
                    playtimeChart.destroy();
                }

                let mainChartTotal = 0;
                $.each(response, function (index, element) {
                    // Get total
                    mainChartTotal += element.playtimeDuration;
                });

                // Convert our data into a dataset we can use for this chart.
                let labels = [];
                let data = [];
                let backgroundColor = [];
                let sum = 0;

                let otherChartTotal = 0;
                let otherChartData = [];
                let otherChartLabels = [];
                let otherChartBgColor = [];
                $.each(response, function(index, element) {
                    let percent = 0;
                    percent = element.playtimeDuration / mainChartTotal * 100;

                    if (percent < 10) {
                        // Keep track of total of Other
                        otherChartTotal += element.playtimeDuration;
                        otherChartData.push(element.playtimeDuration);
                        otherChartLabels.push(element.label);
                        otherChartBgColor.push(element.backgroundColor);
                    } else {
                        labels.push(element.label);
                        data.push(element.playtimeDuration);
                        backgroundColor.push(element.backgroundColor);
                    }
                    sum += element.playtimeDuration;
                });

                if (sum <= 0) {
                    // Show a message
                    if ($('.chart-container .alert-info').length <= 0) {
                        $('.chart-container').append($('<div class="alert alert-info">No display data for Campaign.</div>'))
                    }
                    return;
                }

                let $otherPlaytimeBtns = $('#otherPlaytime .switch-other-main');

                if (otherChartData.length === 1) {
                    // We push only on other slice in main chart
                    labels.push(otherChartLabels);
                    data.push(otherChartData);
                    backgroundColor.push(otherChartBgColor);
                } else if (otherChartData.length > 1) {
                    // We have other slice in chart
                    // Combine the Other slice in Main Chart
                    labels.push('Other');
                    data.push(otherChartTotal);
                    backgroundColor.push('#808080');

                    // Show two buttons Other and Main
                    $otherPlaytimeBtns.show();
                }

                let chartData = {
                    labels: labels,
                    datasets: [
                        {
                            label: 'Display Played Percentage',
                            data: data,
                            backgroundColor: backgroundColor,
                        }],
                };
                let configOptions = {
                    plugins: {
                        legend: {
                            position: 'top',
                        },
                        datalabels: {
                            render: 'percentage',
                            fontColor: 'white',
                            precision: 2,
                        },
                    },
                    maintainAspectRatio: false,
                    animation: {
                        onComplete: function(animation) {
                            // hideLoading();
                        }
                    },
                };

                playtimeChart = drawChart(chartData, configOptions, $('#playtimeChartCanvas'));

                // Update chart config
                updateConfigAsNewObject('playtimeChart', mainChartTotal);

                $otherPlaytimeBtns.find("input").attr("data-other-labels", otherChartLabels);
                $otherPlaytimeBtns.find("input").attr("data-other-data", otherChartData);
                $otherPlaytimeBtns.find("input").attr("data-other-bg-color", otherChartBgColor);

                $otherPlaytimeBtns.find("input").attr("data-main-labels", labels);
                $otherPlaytimeBtns.find("input").attr("data-main-data", data);
                $otherPlaytimeBtns.find("input").attr("data-main-bg-color", backgroundColor);

                $otherPlaytimeBtns.find("input").attr("data-main-total", mainChartTotal);

            }

            // Tab shown/click load relevant table/chart
            $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                let activeTab = $(e.target).attr("href")
                if (result) {
                    if (activeTab === '#spendChartTab') {
                        setSpendChartData($spendChartCanvas, result.table);
                    } else if (activeTab === '#playtimeChartTab') {
                        setPlaytimeChartData($playtimeChartCanvas, result.table);
                    } else {
                        setTabularData(table, result.table);
                    }
                }
            });

            // todo
            table.on('draw', dataTableDraw);
            table.on('processing.dt', dataTableProcessing);
            dataTableAddButtons(table, $('#stats_wrapper').find('.dataTables_buttons'));

            // Apply
            $applyBtn.click(function () {
                $(this).addClass('disabled');
                checkFilterAndApply();
                getData($dataTable.data().url);
            });


            let checkFilterAndApply = function() {

                let reportAddBtn = $("button#reportAddBtn");
                let $parentCampaign = $('#parentCampaignId');

                // If we select a displayId we hide the display group filter
                $parentCampaign.off('change').change( function() {

                    let parentCampaignId = $(this).val();
                    if (parentCampaignId) {
                        $applyBtn.removeClass('disabled');
                        reportAddBtn.removeClass('disabled');
                    } else {
                        $("#parentCampaignId option").remove();
                        $applyBtn.addClass('disabled');
                        reportAddBtn.addClass('disabled');
                    }
                });
                reportAddBtn.attr("href", "{{ url_for("reportschedule.add.form") }}?parentCampaignId=" + $parentCampaign.val() + "&reportName=displayPercentage" );
            };

            imageLoader.hide();
            $applyBtn.addClass('disabled');
            checkFilterAndApply();

            // Bind to form change
            $report.on('change', function() {
                checkFilterAndApply();
            });

            var $campaignSelect = $('#parentCampaignId');
            $campaignSelect.select2({
                ajax: {
                    url: $campaignSelect.data("searchUrl"),
                    dataType: "json",
                    delay: 250,
                    placeholder: 'Campaign',
                    allowClear: true,
                    data: function(params) {

                        var query = {
                            isLayoutSpecific: 0,
                            retired: 0,
                            totalDuration: 0,
                            name: params.term,
                            start: 0,
                            length: 10,
                            columns: [
                                {
                                    "data": "isLayoutSpecific"
                                },
                                {
                                    "data": "campaign"
                                }
                            ],
                            order: [
                                {
                                    "column": 0,
                                    "dir": "asc"
                                },
                                {
                                    "column": 1,
                                    "dir": "asc"
                                }
                            ]
                        };

                        // Set the start parameter based on the page number
                        if (params.page != null) {
                            query.start = (params.page - 1) * 10;
                        }

                        return query;
                    },
                    processResults: function(data, params) {

                        var results = [];
                        var campaigns = [];

                        $.each(data.data, function(index, element) {
                            campaigns.push({
                                "id": element.campaignId,
                                "text": element.campaign
                            });
                        });

                        results.push({
                            "text": $campaignSelect.data('transCampaigns'),
                            "children": campaigns
                        })


                        var page = params.page || 1;
                        page = (page > 1) ? page - 1 : page;

                        return {
                            results: results,
                            pagination: {
                                more: (page * 10 < data.recordsTotal)
                            }
                        }
                    }
                }
            })
        });

        function reportScheduleCallback() {

            let $parentCampaignId = $('#report #parentCampaignId');
            let $newParentCampaignId = $('#reportScheduleAddForm #parentCampaignId');

            appendOptions($newParentCampaignId, $parentCampaignId.find('option:selected').clone());
        }

        function appendOptions(element, options) {

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

                let option = options[i];
                element.append(option).trigger('change');
                $(option).prop('selected', true);
                element.trigger({
                    type: 'select2:select',
                    params: {
                        data: option
                    }
                });
            }
        }
    </script>
{% endblock %}
