<?php

namespace App\Bundle\Yandex;

/*
 * id приложения aaa091c17d734ab08af7cb2455c360fa
 * ссылка получения токена
 * https://oauth.yandex.ru/authorize?response_type=token&client_id=aaa091c17d734ab08af7cb2455c360fa
 */
class Direct 
{
    private $token;
    private $login;
    private $url = 'https://api.direct.yandex.com/json/v5';
    
    function __construct($regionId = false)
    {
        $this->changeRegion($regionId);
    }
    
    public function changeRegion($regionId = false)
    {
        switch ($regionId) {
            case 92:
                // return 'Волгоград';
                $this->token = '';
                $this->login = '';

                break;

            case 93:
                // return 'Воронеж';
                $this->token = 'y0_AgAAAABUjm5UAAgI4QAAAADRC5rdh5RD9KWSSIKGNb0cDBniUfVh6KU';
                $this->login = 'e-16766240';
                
                break;

            case 94:
                // return 'Краснодар';
                $this->token = '';
                $this->login = '';
                
                break;

            case 100:
                // return 'Комфорт';
                $this->token = '';
                $this->login = '';
                
                break;

            case 101:
                // return 'Совёнок';
                $this->token = '';
                $this->login = '';
                
                break;

            case 102:
                // return 'ОМС';
                $this->token = '';
                $this->login = '';
                
                break;

            default:
                // return 'Саратов';
                $this->token = '';
                $this->login = '';

                break;
        }
    }

    public function getError()
    {
        return $this->error;
    }

    /**
     * @param array $params
     * @param string $url
     * @return mixed
     */
    public function Request($params = [], $url, $report = false)
    {

        $headers = array(
            "Authorization: Bearer $this->token",                   // OAuth-токен. Использование слова Bearer обязательно
            "Client-Login: $this->login",                     // Логин клиента рекламного агентства
            "Accept-Language: ru",                            // Язык ответных сообщений
            "Content-Type: application/json; charset=utf-8"   // Тип данных и кодировка запроса
        );
        if ($report == true) {
            $headers []= "processingMode: auto";  // Режим формирования отчета online, offline , auto
            $headers []= "returnMoneyInMicros: false";  // Не выводить в отчете строку с названием отчета и диапазоном дат
            $headers []= "skipReportHeader: true";      // Не выводить в отчете строку с названием отчета и диапазоном дат
            $headers []= "skipColumnHeader: true";      // Не выводить в отчете строку с названиями полей
            $headers []= "skipReportSummary: true";     // Не выводить в отчете строку с количеством строк статистики
        }

        $body = json_encode($params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $curl = curl_init();

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, true);
        curl_setopt($curl, CURLINFO_HEADER_OUT, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

        while (true) {

            $result = curl_exec($curl);

            if (!$result) {

                echo ('Ошибка cURL: '.curl_errno($curl).' - '.curl_error($curl));

                break;

            } else {

                // Разделение HTTP-заголовков и тела ответа
                $responseHeadersSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
                $responseHeaders = substr($result, 0, $responseHeadersSize);
                $responseBody = substr($result, $responseHeadersSize);

                // Получение кода состояния HTTP
                $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

                // Извлечение HTTP-заголовков ответа
                // Идентификатор запроса
                $requestId = preg_match('/RequestId: (\d+)/', $responseHeaders, $arr) ? $arr[1] : false;
                //  Рекомендуемый интервал в секундах для проверки готовности отчета
                $retryIn = preg_match('/retryIn: (\d+)/', $responseHeaders, $arr) ? $arr[1] : 160;

                if ($httpCode == 400) {

                    echo "Параметры запроса указаны неверно или достигнут лимит отчетов в очереди<br>\n";
                    echo "RequestId: {$requestId}<br>\n";
                    echo "JSON-код запроса:<br>{$body}<br>\n";
                    echo "JSON-код ответа сервера:<br>{$responseBody}<br>\n";

                    return $responseBody;

                    break;

                } elseif ($httpCode == 200) {
                    return $responseBody;
                    
                    break;
                } elseif ($httpCode == 201) {

                    echo "Отчет успешно поставлен в очередь в режиме офлайн<br>\n";
                    echo "Повторная отправка запроса через {$retryIn} секунд<br>\n";
                    echo "RequestId: {$requestId}<br>\n";

                    sleep($retryIn);

                } elseif ($httpCode == 202) {

                    echo "Отчет формируется в режиме offline.<br>\n";
                    echo "Повторная отправка запроса через {$retryIn} секунд<br>\n";
                    echo "RequestId: {$requestId}<br>\n";

                    sleep($retryIn);

                } elseif ($httpCode == 500) {

                    echo "При формировании отчета произошла ошибка. Пожалуйста, попробуйте повторить запрос позднее<br>\n";
                    echo "RequestId: {$requestId}<br>\n";
                    echo "JSON-код ответа сервера:<br>\n{$responseBody}<br>\n";

                    break;

                } elseif ($httpCode == 502) {

                    echo "Время формирования отчета превысило серверное ограничение.<br>";
                    echo "Пожалуйста, попробуйте изменить параметры запроса - уменьшить период и количество запрашиваемых данных.<br>";
                    echo "RequestId: {$requestId}<br>";

                    break;

                } else {

                    echo "Произошла непредвиденная ошибка.<br>";
                    echo "RequestId: {$requestId}<br>";
                    echo "JSON-код запроса:<br>{$body}<br>";
                    echo "JSON-код ответа сервера:<br>{$responseBody}<br>";

                    break;

                }
            }
        }
        curl_close($curl);
    }

    /**
     * @return Array|int
     */
    public function getCompanies()
    {
        $params = [
            'method' => 'get',                                // Используемый метод сервиса Campaigns
            'params' => array(
                'SelectionCriteria' => (object)array(
                    'States' => [
                        'ON',
                        'OFF',
                    ],

                ),      // Критерий отбора кампаний. Для получения всех кампаний должен быть пустым
                'FieldNames' => [ // Названия параметров, которые требуется получить
                    "Id",
                    "Name",
                    "State",
                    "Type",
                    ],
 
            )
        ];

        return $this->response($this->Request($params, $this->url . '/campaigns'));
    }

    private function response($data)
    {
        $data = json_decode($data, true);

        if (empty($data['error'])) {
            return $data['result'];
        }

        return $data['error'];
    }

    public function getRegions()
    {
        $params = [
            "method" => "get",
  			"params" => [
    			"DictionaryNames" => [
    					//"Currencies",
    					//"MetroStations",
    					"GeoRegions",
    					//"TimeZones",
    					//"Constants",
    				//	"AdCategories",
    				//	"OperationSystemVersions",
    				//	"ProductivityAssertions",
    				//	"SupplySidePlatforms",
    				//	"Interests",
    				//	"AudienceCriteriaTypes",
    				//	"AudienceDemographicProfiles",
    				//	"AudienceInterests" 
    				], 
    			],
        	];

        return $this->response($this->Request($params, $this->url . '/dictionaries'));
    }

    public function getKey($group)
    {
        $params = [
            'method' => 'get',                                // Используемый метод сервиса Campaigns
            'params' => [
                'SelectionCriteria' => [
                    'AdGroupIds' => $group,
                ],
                'FieldNames' => [
                     "Id",
                     "Keyword",
                     "State",
                     "Status",
                     "ServingStatus",
                     "AdGroupId",
                     "CampaignId",
                     "Bid",
                     "ContextBid",
                     "StrategyPriority",
                     "UserParam1",
                     "UserParam2",
                     "Productivity",
                     "StatisticsSearch",
                     "StatisticsNetwork",
                ]
            ]
        ];

        return $this->response($this->Request($params, $this->url . '/keywords'));
    }

    public function getGroups($CampaignIds = array())
    {
        $params = [
            'method' => 'get',                                // Используемый метод сервиса Campaigns
            'params' => [
                'SelectionCriteria' => [
                    'CampaignIds' => $CampaignIds,
                    'Statuses' => [
                        "ACCEPTED", 
                        "DRAFT", 
                        "MODERATION", 
                        "PREACCEPTED", 
                        "REJECTED"
                    ],
                ],
                'FieldNames' => [
                    "Id",
                    "CampaignId",
                    "Name",
                    "RegionIds",
                    "ServingStatus",
                    "Status",
                    "Type",
                ]
            ]
        ];

        return $this->response($this->Request($params, $this->url . '/adgroups'));
    }

    public function getAds($CampaignIds = array())
    {
        $params = [
            'method' => 'get',                                // Используемый метод сервиса Campaigns
            'params' => [
                'SelectionCriteria' => [
                    'CampaignIds' => $CampaignIds,
                ],
                'FieldNames' => [
                    "Id", 
                    "AdGroupId", 
                    "CampaignId", 
                    "State", 
                    "StatusClarification", 
                    "Type", 
                ],
                'TextAdFieldNames' => [
                    "Title", 
                    "Title2", 
                    "Text", 
                    "Href", 
                    "Mobile", 
                    "DisplayUrlPath", 
                ],
            ]
        ];

        return $this->response($this->Request($params, $this->url . '/ads'));
    }

    public function getReport()
    {
        $params = [
            "params" => [
                "SelectionCriteria" =>  (object) [
                    // 'DateFrom' => \date('Y-m-d', strtotime('-7 day')), 
                    // 'DateTo' => \date('Y-m-d', strtotime($dateTo))
                ],
                "FieldNames" => [
                    "Week", 
                    "CampaignId",
                    "AdGroupId",
                    "AdId",
                    "Impressions", 
                    "Clicks", 
                    "Cost", 
                    "Conversions" 
                ],
                "ReportName" => 'отчет -'.time(),
                "ReportType" => "AD_PERFORMANCE_REPORT",
                "DateRangeType" => "LAST_WEEK",
                "Format" => "TSV",
                "IncludeVAT" => "NO",
                "IncludeDiscount" => "NO"
            ]
        ];

        $response = $this->Request($params, $this->url . '/reports', true);
        
        if ($jsonResponse = json_decode($response, true)) {
            return $jsonResponse['error'];
        }
        
        $linearray = [];
        
        foreach(explode("\n", $response) as $key =>  $line  ) {
            if(!empty($line)) {
                list(
                    $date, 
                    $campaignId,
                    $adGroupId,
                    $adId,
                    //$LocationOfPresenceId,
                    $impressions,
                    $clicks,
                    $cost,
                    $conversions
                    //$AdFormat,
                    //$AdNetworkType,
                    //$Age
                ) = explode("\t", $line);               
                
                $linearray []= array(
                     'Date' => $date,
                     'CampaignId' => $campaignId,  
                     'AdGroupId' => $adGroupId,   
                     'AdId' => $adId,    
                     //'LocationOfPresenceId' => $LocationOfPresenceId,   
                     'Impressions' => $impressions, 
                     'Clicks' => $clicks,  
                     'Cost' => $cost,    
                     'Conversions' => $conversions,    
                     //'AdFormat' => $AdFormat,    
                     //'AdNetworkType' => $AdNetworkType,   
                     //'Age' => $Age,
                );
            }
        }

        return $linearray;
    }
}
