$(document).ready(function(){

    var
        $table = $('#table-line'),
        $tableHeader = $('<thead>'),
        $tableContent = $('<tbody>'),
        $tableBody = $table.find('tbody').first(),
        activeLinesSwitchSelector = '.b-filter__switch.current-metric:not(.metric-data) .b-filter__switch-item',
        $activeLinesSwitch = $(activeLinesSwitchSelector),
        selectorTableTimeSwitch = '.b-filter__switch.time-table .m-filter__switch-item_active',
        selectorActiveData = '.b-filter__switch.metric-data .m-filter__switch-item_active',
        timeTableType,
        activeLines = [],
        currentActiveLine,
        metric,
        dataTable,
        specialFields = $.ReportsConf.SpecialFields,
        percentsFields = $.ReportsConf.PercentsFields,
        notCategoryIdFields = $.ReportsConf.NotCategoryIdFields,
        bySiteState = false,
        minstatCommonGroupFields = ['sspMoney', 'cpm', 'cpc', 'sspSiteMoney', 'siteCpm', 'siteCpc', 'sspSystemMoney', 'systemCpm', 'systemCpc'];
    
    function valueFormat(value)
    {
        var
            currencyFields = $.ReportsConf.CurrencyFields,
            isCurrencyValue = currencyFields.indexOf(currentActiveLine) > -1,
            format = (isCurrencyValue) ? d3.format(',.2f') : d3.format(',.0f');
        
        if (currentActiveLine == 'cpm') {
            format = d3.format(',.3f');
        }
        
        if (percentsFields.indexOf(currentActiveLine)>=0) {
            format = d3.format(".2%");
        }
    
        return format(value);
    }
    
    function RenderCompare(dataLineChartStat)
    {
        // Часовые данные для таблицы
        var
            days = [],
            dataPeriod = [],
            i,j,sumInterval;
        
        // Формируем список дней:
        for (var key in dataLineChartStat) {
            if (['period','metric','type'].indexOf(key)<0) days.push(key);
        }

        // Формируем список часов:
        for (i = 0; i < dataLineChartStat['period'].length; i++) {
            if (i % 12 == 0) {
                dataPeriod.push(dataLineChartStat['period'][i]);
            }
        }

        activeLines.forEach(function(activeLine) {
            
            //console.log('AAA dataTable: ', dataTable);
            
            var dataPart = dataTable[activeLine];
            for (i = 0; i < days.length; i++) {
                var dataCorrectTime = [];
                
                if (specialFields.indexOf(activeLine)>=0)
                {
                    var
                        runRatioValue,
                        calcParams = $.ReportsConf.GetCalculationParams(metric, activeLine),
                        koef = calcParams['k'],
                        fieldNum = calcParams['n'],
                        fieldDen = calcParams['d'],
                        sumRunCnt = 0,
                        sumLoadCnt = 0;
                    
                    for (j = 0; j < dataLineChartStat[days[i]][activeLine].length; j++) {
                        sumRunCnt += dataLineChartStat[days[i]][fieldNum][j];
                        sumLoadCnt += dataLineChartStat[days[i]][fieldDen][j];

                        if ((j+1) % 12 == 0) {
                            runRatioValue = (sumLoadCnt == 0) ? 0 : sumRunCnt/sumLoadCnt*koef;
                            dataCorrectTime.push(runRatioValue);
                            sumRunCnt = 0;
                            sumLoadCnt = 0;
                        }
                    }

                    if (j % 12 != 0) {
                        runRatioValue = (sumLoadCnt == 0) ? 0 : sumRunCnt/sumLoadCnt*koef;
                        dataCorrectTime.push(runRatioValue);
                    }
                    
                }
                else
                {
                    sumInterval = 0;
                    
                    //console.log('AAA 111 activeLine = ', activeLine);
                    //console.log('AAA 111 dataLineChartStat = ', dataLineChartStat[days[i]]);
                    
                    for (j = 0; j < dataLineChartStat[days[i]][activeLine].length; j++) {
                        sumInterval += dataLineChartStat[days[i]][activeLine][j]*5;
                        if ((j+1) % 12 == 0) {
                            dataCorrectTime.push(sumInterval);
                            if (timeTableType != 'sum')
                            {
                                sumInterval = 0;
                            }
                        }
                    }

                    if (j % 12 != 0) {
                        dataCorrectTime.push(sumInterval);
                    }
                }
                
                dataPart[i] = dataCorrectTime;
            }
            
        });
        

        for (i = dataPeriod.length-1; i >= 0; i--) {

            var
                currentDay = new Date(days[1] + ' ' + dataPeriod[i]),
                now = new Date(),
                classTd,
                classTimeTd = (currentDay > now || ((now.getTime()-currentDay.getTime())<60*60*1000)) ? ' class="time-not-come"' : '';

            var
                date = dataPeriod[i],
                values = {},
                diff, style;
           
            activeLines.forEach(function(activeLine){
                currentActiveLine = activeLine;

                // Если данных нет, то зануляем их
                if (!dataTable[activeLine][1][i]) {
                    dataTable[activeLine][1][i] = 0;
                }

                diff = dataTable[activeLine][1][i]-dataTable[activeLine][0][i];
                style = (diff < 0) ? 'negative' : '';
                values[activeLine] = '<div class="double-val">' + valueFormat(dataTable[activeLine][1][i]) + '<br>' + valueFormat(dataTable[activeLine][0][i]) + '</div>' + '<span class="diff '+ style +'">' + valueFormat(diff) + '</span>';
            });

            
            $row = $('<tr'+ classTimeTd +'>');
            $row.append($('<td>').html(date));
            activeLines.forEach(function(item){
                classTd = ((metric == 'minstat') && (minstatCommonGroupFields.indexOf(item) > -1)) ? ' class="in-common-group"' : '';
                $row.append($('<td'+ classTd +'>').html(values[item]));
            });
            $row.appendTo($tableContent);
        }           
    }
    
    function RenderDay(dataLineChartStat)
    {
        var
            dataPeriod = [],
            i,j,sumInterval;
        
        // Формируем список часов:
        for (i = 0; i < dataLineChartStat['period'].length; i++) {
            if (i % 12 == 0) {
                dataPeriod.push(dataLineChartStat['period'][i]);
            }
        }

        activeLines.forEach(function(activeLine) {
            var dataCorrectTime = [];
            if (specialFields.indexOf(activeLine)>=0)
            {
                var
                    runRatioValue,
                    calcParams = $.ReportsConf.GetCalculationParams(metric, activeLine),
                    koef = calcParams['k'],
                    fieldNum = calcParams['n'],
                    fieldDen = calcParams['d'],
                    sumRunCnt = 0,
                    sumLoadCnt = 0;

                for (j = 0; j < dataLineChartStat[activeLine].length; j++) {
                    sumRunCnt += dataLineChartStat[fieldNum][j];
                    sumLoadCnt += dataLineChartStat[fieldDen][j];
                    if ((j+1) % 12 == 0) {
                        runRatioValue = (sumLoadCnt == 0) ? 0 : sumRunCnt/sumLoadCnt*koef;
                        dataCorrectTime.push(runRatioValue);
                        sumRunCnt = 0;
                        sumLoadCnt = 0;
                    }
                }
                if ((j+1) % 12 != 0) {
                    runRatioValue = (sumLoadCnt == 0) ? 0 : sumRunCnt/sumLoadCnt*1;
                    dataCorrectTime.push(runRatioValue);
                }
            }
            else
            {
                sumInterval = 0;
                for (j = 0; j < dataLineChartStat[activeLine].length; j++) {
                    sumInterval += dataLineChartStat[activeLine][j]*5;
                    if ((j+1) % 12 == 0) {
                        dataCorrectTime.push(sumInterval);
                        if (timeTableType != 'sum')
                        {
                            sumInterval = 0;
                        }
                    }
                }
                if ((j+1) % 12 != 0) {
                    dataCorrectTime.push(sumInterval);
                }

            }
            dataTable[activeLine] = dataCorrectTime;
        });

        for(i = dataPeriod.length-1; i >= 0; i--) {

            var
                currentDay = new Date($('#date-value-1').val() + ' ' + dataPeriod[i]),
                now = new Date(),
                classTd,
                classTimeTd = ((now.getTime()-currentDay.getTime())<60*60*1000) ? ' class="time-not-come"' : '';

            // Не отображаем даные для ненаступившего времени:
            if (currentDay > now) {
                continue;
            }

            var
                date = dataPeriod[i],
                values = {};
            
            activeLines.forEach(function(activeLine){
                currentActiveLine = activeLine;

                // Если данных нет, то зануляем их
                if (!dataTable[activeLine][i]) {
                    dataTable[activeLine][i] = 0;
                }

                values[activeLine] = valueFormat(dataTable[activeLine][i]);
            });

            $row = $('<tr'+ classTimeTd +'>');
            $row.append($('<td>').html(date));
            activeLines.forEach(function(item){
                classTd = ((metric == 'minstat') && (minstatCommonGroupFields.indexOf(item) > -1)) ? ' class="in-common-group"' : '';
                $row.append($('<td'+ classTd +'>').html(values[item]));
            });
            $row.appendTo($tableContent);
        }           
    }
    
    function RenderInterval(dataLineChartStat)
    {
        var dataPeriod = dataLineChartStat['period'],
            classTd;

        dataTable = dataLineChartStat;

        // Добавляем строку "Итого":
        $row = $('<tr style="font-weight: bold;">');
        $row.append($('<td>').html("Итого"));
        activeLines.forEach(function(item){
            currentActiveLine = item;
            
            if (specialFields.indexOf(item)>=0)
            {
                var
                    calcParams = $.ReportsConf.GetCalculationParams(metric, item),
                    koef = calcParams['k'],
                    fieldNum = calcParams['n'],
                    fieldDen = calcParams['d'],
                    sumRunCnt = 0,
                    sumLoadCnt = 0,
                    runRatioValue;
                                
                for(var i = dataPeriod.length-1; i >= 0; i--) {
                    sumRunCnt += dataTable[fieldNum][i];
                    sumLoadCnt += dataTable[fieldDen][i];
                }
                runRatioValue = (sumLoadCnt == 0) ? 0 : sumRunCnt/sumLoadCnt*koef;
                
                classTd = ((metric == 'minstat') && (minstatCommonGroupFields.indexOf(item) > -1)) ? ' class="in-common-group"' : '';
                $row.append($('<td'+ classTd +'>').html(valueFormat(runRatioValue)));
            }
            else
            {
                var totalValue = 0;
                for(var i = dataPeriod.length-1; i >= 0; i--) {
                    totalValue += dataTable[item][i];
                }
                
                classTd = ((metric == 'minstat') && (minstatCommonGroupFields.indexOf(item) > -1)) ? ' class="in-common-group"' : '';
                $row.append($('<td'+ classTd +'>').html(valueFormat(totalValue)));
            }
            
        });
        $row.appendTo($tableContent);

        for(var i = dataPeriod.length-1; i >= 0; i--) {

            var
                date = dataPeriod[i],
                values = {};

            activeLines.forEach(function(activeLine){
                currentActiveLine = activeLine;
                values[activeLine] = valueFormat(dataTable[activeLine][i]);
            });

            $row = $('<tr>');
            $row.append($('<td>').html(date));
            activeLines.forEach(function(item){
                classTd = ((metric == 'minstat') && (minstatCommonGroupFields.indexOf(item) > -1)) ? ' class="in-common-group"' : '';
                $row.append($('<td'+ classTd +'>').html(values[item]));
            });
            $row.appendTo($tableContent);
        }
    }
    
    function RenderByCategories(dataLineChartStat)
    {        
        var
            dataTable = {},
            siteId, cat,
            classTd;
    
        for(siteId in dataLineChartStat){
            if (notCategoryIdFields.indexOf(siteId) < 0) {
                
                dataTable[siteId] = {};
                for (var key in dataLineChartStat[siteId]) {
                   dataTable[siteId][key] = dataLineChartStat[siteId][key];
                }
                
                for(cat in dataTable[siteId]) {
                    var sum = 0;
                    dataTable[siteId][cat].forEach(function(item){sum += item});
                    dataTable[siteId][cat] = sum;
                }
                
                dataTable[siteId]['cpm'] = (dataTable[siteId]['sspViewsCnt'] == 0) ? 0 : dataTable[siteId]['sspMoney'] / dataTable[siteId]['sspViewsCnt'] * 1000;
                dataTable[siteId]['ctr'] = (dataTable[siteId]['sspViewsCnt'] == 0) ? 0 : dataTable[siteId]['sspClicksCnt'] / dataTable[siteId]['sspViewsCnt'] * 1;
                dataTable[siteId]['cpc'] = (dataTable[siteId]['sspClicksCnt'] == 0) ? 0 : dataTable[siteId]['sspMoney'] / dataTable[siteId]['sspClicksCnt'] * 100;
                dataTable[siteId]['siteRatio'] = (dataTable[siteId]['sspMoney'] == 0) ? 0 : dataTable[siteId]['sspSiteMoney'] / dataTable[siteId]['sspMoney'];
                dataTable[siteId]['systemRatio'] = (dataTable[siteId]['sspMoney'] == 0) ? 0 : dataTable[siteId]['sspSystemMoney'] / dataTable[siteId]['sspMoney'];
                dataTable[siteId]['sumRatio'] = (dataTable[siteId]['sspMoney'] == 0) ? 0 : dataTable[siteId]['sspMoney'] / dataTable[siteId]['sspMoney'];
            }
        }
        
        // Добавляем строку "Суммарно":
        $('thead', $table).addClass('sortable');
        $row = $('<tr style="font-weight: bold;">');
        $row.append($('<td>').html('<b class="common-sum">Суммарно</b>'));
        activeLines.forEach(function(item){
            currentActiveLine = item;
            
            if (specialFields.indexOf(item)>=0)
            {
                var
                    calcParams = $.ReportsConf.GetCalculationParams(metric, item),
                    koef = calcParams['k'],
                    fieldNum = calcParams['n'],
                    fieldDen = calcParams['d'],
                    sumRunCnt = 0,
                    sumLoadCnt = 0,
                    runRatioValue;
                
                for(siteId in dataTable){
                    sumRunCnt += dataTable[siteId][fieldNum];
                    sumLoadCnt += dataTable[siteId][fieldDen];
                }
                
                runRatioValue = (sumLoadCnt == 0) ? 0 : sumRunCnt/sumLoadCnt*koef;
                
                classTd = ((metric == 'minstat') && (minstatCommonGroupFields.indexOf(item) > -1)) ? ' class="in-common-group"' : '';
                $row.append($('<td'+ classTd +'>').html(valueFormat(runRatioValue)));
            }
            else
            {
                var totalValue = 0;
                for(siteId in dataTable){
                    totalValue += dataTable[siteId][item];
                }
                
                classTd = ((metric == 'minstat') && (minstatCommonGroupFields.indexOf(item) > -1)) ? ' class="in-common-group"' : '';
                $row.append($('<td'+ classTd +'>').html(valueFormat(totalValue)));
            }
            
        });
        $row.appendTo($tableContent);
                
        // Сортировка строк в таблице:
        var
            sortField = 'sspMoney',
            $selectedField = $('#table-line thead.metric.sortable th b.selected'),
            isDesc = true;
        
        if ($selectedField.length > 0) {
            sortField = $selectedField.attr('id');
            isDesc = $selectedField.hasClass('desc');
        } else {
            $('#table-line thead.metric.sortable th b[id="' + sortField + '"]').addClass('selected').addClass('desc');
        }
        
        var dataTableForSort = [];
        for(siteId in dataTable) {
            var dataItem = dataTable[siteId];
            dataItem['id'] = (dataLineChartStat.byCountries) ? siteId : parseInt(siteId);
            dataTableForSort.push(dataItem);
        }
        dataTableForSort.sort(function(a,b){
            if (isDesc) {
                return b[sortField]-a[sortField];
            } else {
                return a[sortField]-b[sortField];
            }
            
        });
        
        var
            byCategory = $.ReportsConf.GetCategoryType(dataLineChartStat),
            selectedCategoriesId = $.TableStat.CheckedCategories(),
            isBySiteState = $.TableStat.GetSiteState();
        
        dataTableForSort.forEach(function(item){
            
            // Не выводим зоны, у которых 0 кликов и меньше 5 показов
            if (dataLineChartStat.byZones && item['sspClicksCnt']==0 && item['sspViewsCnt']<5) {
                return false;
            }
            
            var
                values = {},
                isChecked = ((selectedCategoriesId && selectedCategoriesId.indexOf(item['id'])>-1) || isBySiteState) ? 'checked' : '';

            activeLines.forEach(function(activeLine){
                currentActiveLine = activeLine;
                values[activeLine] = valueFormat(item[activeLine]);
            });

            $row = $('<tr>');
            
            var categoryInfo = (byCategory == 'byCountries') ? dataLineChartStat[byCategory][item['id']] : '<span class="site-domain">' + dataLineChartStat[byCategory][item['id']] + '<span>';
            $row.append($('<td>').html('<input type="checkbox" ' + isChecked + ' id="' + item['id'] + '" name="show-filters">[' + item['id'] + '] ' + categoryInfo));
            
            activeLines.forEach(function(item){
                $row.append($('<td>').html(values[item]));
            });
            $row.appendTo($tableContent);
        });
        
        $.TableStat.SetSiteState(false);
    }
    
    /*
    // Формируем список переключателей (категорий) activeLines:
    $activeLinesSwitch.each(function(){
        activeLines.push($(this).data('filter-category'));
    });
    */
    
    $.extend({
        TableStat: {
            Render: function(dataLineChartStat) {
                
                // Определяем тип метрики:
                metric = dataLineChartStat.metric;

                // Формируем список переключателей (категорий) activeLines:
                activeLines = [];
                $(activeLinesSwitchSelector).each(function(){
                    if (dataLineChartStat.metric == 'minstat')
                    {
                        var activeData = $(selectorActiveData).data('filter-category');
                        var activeLineValue = $(this).data('filter-category');
                        
                        if (activeLineValue == 'money') {
                            /*
                            if (activeData == 'sum') activeLineValue = 'sspMoney';
                            if (activeData == 'site') activeLineValue = 'sspSiteMoney';
                            if (activeData == 'system') activeLineValue = 'sspSystemMoney';
                            */
                            activeLineValue = ['sspMoney', 'cpm', 'cpc'];
                        }
                        if (activeLineValue == 'ratio') {
                            /*
                            if (activeData == 'sum') activeLineValue = 'sumRatio';
                            if (activeData == 'site') activeLineValue = 'siteRatio';
                            if (activeData == 'system') activeLineValue = 'systemRatio';
                            */
                            activeLineValue = 'systemRatio';
                        }
                        if (activeLineValue == 'cpm') {
                            /*
                            if (activeData == 'sum') activeLineValue = 'cpm';
                            if (activeData == 'site') activeLineValue = 'siteCpm';
                            if (activeData == 'system') activeLineValue = 'systemCpm';
                            */
                            activeLineValue = ['sspSiteMoney', 'siteCpm', 'siteCpc'];
                        }
                        if (activeLineValue == 'cpc') {
                            /*
                            if (activeData == 'sum') activeLineValue = 'cpc';
                            if (activeData == 'site') activeLineValue = 'siteCpc';
                            if (activeData == 'system') activeLineValue = 'systemCpc';
                            */
                            activeLineValue = ['sspSystemMoney', 'systemCpm', 'systemCpc'];
                        }
                        
                        //console.log('AAA activeData: ', activeData, ' activeLineValue: ', activeLineValue);
                        if (Array.isArray(activeLineValue)) {
                            activeLineValue.forEach(function(item) {
                                activeLines.push(item);
                            });
                        } else {
                            activeLines.push(activeLineValue);
                        }
                    } 
                    else
                    {
                        activeLines.push($(this).data('filter-category'));
                    }
                    
                });

                //console.log('AAA TableStat render: ', dataLineChartStat);
                //console.log('AAA activeLines: ', activeLines);
                
                timeTableType = $(selectorTableTimeSwitch).data('filter-category');

                dataTable = {};
                activeLines.forEach(function(item){
                    dataTable[item] = [];
                });

                $table.removeClass('compare');
                $('thead', $table).removeClass('sortable');

                if (dataLineChartStat.bySites || dataLineChartStat.byZones || dataLineChartStat.byCountries) {
                    RenderByCategories(dataLineChartStat);
                }
                else
                {
                    if (dataLineChartStat.type == 'compare') {
                        $table.addClass('compare');
                        RenderCompare(dataLineChartStat);
                    }

                    if (dataLineChartStat.type == 'day') {
                        RenderDay(dataLineChartStat);
                    }

                    if (dataLineChartStat.type == 'interval') {
                        RenderInterval(dataLineChartStat);
                    }
                }

                var headerTitle = (dataLineChartStat.bySites) ? 'Сайты' : 'Время';
                $('thead tr[data-metric="' + metric + '"] th:first').text(headerTitle);

                $tableBody.html('').append($tableContent.children());
                
            },
            // Определяем список сайтов (зон, стиран) отмеченных галочками в таблице
            CheckedCategories: function() {
                var listSites = [];
                $('input', $table).each(function(){
                    if ($(this).is(":checked")) {
                        if (!isNaN(parseInt($(this).attr('id')))) {
                            listSites.push(parseInt($(this).attr('id')));
                        } else {
                            listSites.push($(this).attr('id'));
                        }
                    }
                })
                return (listSites.length == 0) ? false : listSites;
            },
            // Устанавливаем состояние "по сайту" (при клике на сайт в таблице)
            SetSiteState: function(state) {
                bySiteState = state;
            },
            // Получаем состояние "по сайту"
            GetSiteState: function() {
                return bySiteState;
            },
        }
    });

});

