<?php

namespace App\Model;

use DateTime;

class Statistics 
{   
    private $hashSolt = '';
    
    public function __construct(/*Sites $sites, Zones $zones, $countries*/) 
    {
        $this->hashSolt = 'FsRpCKc021PzwqOR8o1mXLe8AIS6YmnfkDvECBY6MzGWHhceS4EvdOnW7dYHt7AA';
    }

    
    // Данные по отчетам фидов
    public function getFeedStatData($report_type, $feed_id_list, $dates, $report_conf)
    {
        
        $timeDiff = (strtotime($dates[1])-strtotime($dates[0]))/(24*60*60);
        // Определяем разрешение выборки (группировку) по времени:
        if ($timeDiff == 0) // Одни сутки
        {
            $dates_group = "Min";
        }
        else                // Несколько суток
        {
            $dates_group = "Day";
        }
        
        $dates = array(
            'group' => $dates_group,
            'start'  => $dates[0], 
            'end'  => $dates[1],
        );
        
        // Параметры запроса по типу отчета:
        $type = $report_conf['type'];
        $fields = $report_conf['fields'];
                
        // Данные для запроса:
        if ($report_type == 'common') {
            $dataRequest = array(
                'method' => "reports",
                'data' => array(
                    'type' => $type,
                    'filters'  => array(
                        'FeedID' => array('values' => $feed_id_list),
                    ),
                    'fields'  => $fields,
                    'dates' => $dates,
                )      
            );
        }
        
        if ($report_type == 'transaction') {
            $dataRequest = array(
                'method' => $type,
                'data' => array(
                    'feed_id' => 10003,
                    'start_date' => $dates['start'],
                    'end_date' => $dates['end'],
                )      
            );
        }
        
        //return $dataRequest;
        $stats = $this->apiRequest($dataRequest);
        //return $stats;
        
        // В запросе ошибка или отсутствуют данные для статистики:
        if ($stats['status'] == 'Error') {
            return $stats;
        }
        if ($stats['data'] == []) {
            return null;
        }
        
        
        $dataStats = array();
        $dataStats['report'] = $report_type;
        
        // Данные для отчета 'common':
        if ($report_type == 'common') {
        
            $period = array();

            // Формируем данные для временного промежутка
            function AddDataStats(&$data_stats, $data, $date_type)
            {
                $min_koef = ($date_type == 'interval') ? 1 : 5;
                foreach ($data as $cat=>$value) {
                    $data_stats[$cat][] = $value/$min_koef;
                }
                $data_stats['AdMoney'][] = 224 * $data['Orders']; // временно
            }

            // Формируем пустые данные для временного промежутка
            function AddDataStatsNull(&$data_stats, $cats)
            {
                foreach ($cats as $cat) {
                    $data_stats[$cat][] = 0;
                }
                $data_stats['AdMoney'][] = 0; // временно
            }

            // Логика формирования данных по временному интервалу:
            if (false) {
                if ($timeDiff == 0) // Одни сутки
                {
                    $dataStats['type'] = 'day';

                    // Формируем пустые данные (для отсутствующих значений во временной точке):
                    foreach ($stats['data']['Day'] as $day=>$value_day) {
                        foreach ($value_day['Min'] as $min=>$data) {
                            $data_null = $data;
                            break;
                        }
                        break;
                    }
                    foreach ($data_null as $key=>$value) {
                        $data_null[$key] = 0;
                    }
                    // Формируем 5-минутные интервалы:
                    for ($i=0; $i<288; $i++) {
                        $min = $i * 60 * 5;
                        $period[] = gmdate("H:i", $min);
                    }

                    foreach ($stats['data']['Day'] as $day) {
                        // Формируем временные интервалы, для которых есть значения:
                        $dates_min = [];
                        foreach (array_keys($day['Min']) as $min) {
                            $dates_min[date("H:i", strtotime($min))] = $min;
                        }

                        foreach ($period as $min_value) {
                            $value_min = ($dates_min[$min_value]) ? $day['Min'][$dates_min[$min_value]] : $data_null;
                            AddDataStats($dataStats, $value_min, $metric, $dataStats['type']);
                        }
                    }

                }
                elseif (!$by_days) // Набор дат
                {
                    $dataStats['type'] = 'compare';

                    // Формируем пустые данные (для отсутствующих значений во временной точке):
                    foreach ($stats['data']['Day'] as $day=>$value_day) {
                        foreach ($value_day['Min'] as $min=>$data) {
                            $data_null = $data;
                            break;
                        }
                        break;
                    }
                    foreach ($data_null as $key=>$value) {
                        $data_null[$key] = 0;
                    }
                    // Формируем 5-минутные интервалы:
                    for ($i=0; $i<288; $i++) {
                        $min = $i * 60 * 5;
                        $period[] = gmdate("H:i", $min);
                    }

                    foreach ($stats['data']['Day'] as $day=>$value_day) {
                        $dataStats[date("Y-m-d", strtotime($day))] = [];
                        // Формируем временные интервалы, для которых есть значения:
                        $dates_min = [];
                        foreach (array_keys($value_day['Min']) as $min) {
                            $dates_min[date("H:i", strtotime($min))] = $min;
                        }

                        foreach ($period as $min_value) {
                            $data = ($dates_min[$min_value]) ? $value_day['Min'][$dates_min[$min_value]] : $data_null;
                            AddDataStats($dataStats[date("Y-m-d", strtotime($day))], $data, $metric, $dataStats['type']);
                        }
                    }

                }
                else // Несколько суток
                {
                    $dataStats['type'] = 'interval';
                    foreach ($stats['data']['Day'] as $day=>$value_day) {
                        $period[] = $day;
                        AddDataStats($dataStats, $value_day, $metric, $dataStats['type']);
                    }
                }
            }

            $dataStats['type'] = 'interval';

            // Спискок всех дат из запроса стастистики:
            $all_period = array();
            $begin = new DateTime($dates['start']);
            $end   = new DateTime($dates['end']);
            for($i = $begin; $i <= $end; $i->modify('+1 day')){
                $all_period[] = $i->format("Y-m-d");
            }

            // Список дат, полученных в статистике: 
            $stat_days = array_keys($stats['data']['Day']);
            // Список категорий в данных статистики: 
            $stat_cats = array_keys($stats['data']['Day'][$stat_days[0]]);

            foreach ($all_period as $day_item) {
                $item = new DateTime($day_item);
                $stat_from = new DateTime($stat_days[0]);
                $stat_to = new DateTime($stat_days[count($stat_days)-1]);

                //if (($item>= $stat_from) && ($item<= $stat_to)) {
                if (($item>= $stat_from)) {
                    $period[] = $day_item;
                    if ($stats['data']['Day'][$day_item]) {
                        AddDataStats($dataStats, $stats['data']['Day'][$day_item], $dataStats['type']);
                    } else {
                        AddDataStatsNull($dataStats, $stat_cats);
                    }
                }
            }

            /*
            foreach ($stats['data']['Day'] as $day=>$value_day) {
                $period[] = $day;
                AddDataStats($dataStats, $value_day, $dataStats['type']);
            }
            */
            
            $dataStats['period'] = $period;
        }
        
        // Данные для отчета 'transaction':
        if ($report_type == 'transaction') {
            
            $dataStats['period'] = [];
            $dataStats['Timestamp'] = [];
            $dataStats['OrderSum'] = [];
            $dataStats['Basket'] = [];
            
            foreach ($stats['data'] as $item) {
                $dataStats['period'][] = $item['ForeignID'];
                $dataStats['Timestamp'][] = $item['Timestamp'];
                $dataStats['OrderSum'][] = $item['OrderSum'];
                $dataStats['Basket'][] = $item['Basket'];
            }
        }
        
        $stats = $dataStats;
        return $stats;
    }
    
    
    
    
    // Запрос к API:
    private function apiRequest($data) 
    {
        //return $data;
        $playload = json_encode($data);
        
        $url = 'http://stat.instraroam.net/json/'.md5($playload . $this->hashSolt);
        //$url = 'https://9261bdc7.ngrok.io/json/'.md5($playload . $this->hashSolt);
        
        $cl = curl_init();
        curl_setopt($cl, CURLOPT_URL, $url);
        curl_setopt($cl, CURLOPT_POST, true);
        curl_setopt($cl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($cl, CURLOPT_HTTPHEADER, array(
            'Content-Type:application/json'
        ));        
        curl_setopt($cl, CURLOPT_POSTFIELDS, $playload);
        
        $result = curl_exec($cl);
        $info = curl_getinfo($cl);
        curl_close($cl);
        
        if($info['http_code'] != 200) {
            throw new \Exception('Error. ' . $info['http_code']);
            //throw new \Exception('Error. ' . $info['http_code'] . ' json-data: '. json_encode($data)); // для передачи данных json-запроса
        }
        
        return json_decode($result, 1);
    }
    
}
