<?php
/**
 * Copyright (c) 2016 Serhii Borodai <clarifying@gmail.com>.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 *
 */

namespace App\Action\User;


use App\Action\Common;
use App\Authentication\UserService;
use App\Model\Users;
use App\Model\Statistics;
use App\Model\Providers;
use App\Model\Feeds\Feeds;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\HtmlResponse;
use Zend\Diactoros\Response\JsonResponse;
use Zend\Diactoros\Response\RedirectResponse;
use Zend\Hydrator\DelegatingHydrator;


/**
 * Class Cabinet
 * @package App\Action\User
 */
class Cabinet extends Common
{
    const ACTION_STAT = 'stat';
    const ACTION_CATS = 'cats';

    /**
     * @param ServerRequestInterface $request
     * @param ResponseInterface $response
     * @param callable|null $next
     * @return HtmlResponse
     */
    function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
    {  
        
        /** @var \App\Model\Statistics $stats */
        $stats = $this->container->get(Statistics::class);
        
        if($request->getMethod() == 'POST') {
            
            try {
                switch ($request->getAttribute('action')) {
                    case self::ACTION_STAT:
                        $response = $this->getStatData($request);
                        break;
                    case self::ACTION_CATS:
                        $response = $this->editCatsData($request);
                        break;
                    default:
                }
            } catch(\Exception $e) {
                $data = [
                    'result' => false,
                    'msg' => $e->getMessage(),
                ];
                $response = new JsonResponse($data);
            }
            return $response;
            
        //} else {
        }
        elseif($request->getAttribute('action') == self::ACTION_STAT)
        {
            
            try {

                /** @var UserService $auth */
                $auth = $this->container->get(UserService::class);
                $userId = $auth->getIdentity()->getId();

                /** @var \App\Model\Feeds $feedsModel */
                $feedsModel = $this->container->get(Feeds::class);
                $feeds = $feedsModel->findAll(['clientid' => $userId])->toArray();
                //$feed_id_list = $feedsModel->getIdListByUser($userId);
                
                if ($feeds) {
                    
                    // Фиды пользователя:
                    $feed_id_list = [];
                    foreach($feeds as $feed_item) {
                        $feed_id = $feed_item['id'];
                        if (!in_array($feed_id, $feed_id_list)) {
                            $feed_id_list[] = $feed_id;
                        }
                    }

                    $report_type = $request->getAttribute('report');

                    // Текущий месяц:
                    $current_period = 'current_month';
                    $dates = [date('Y-m-01'), date('Y-m-d')];

                    $reports_conf = $this->container->get('config')['feed_conf']['reports'];
                    $report_conf = $reports_conf[$report_type];
                    
                    // Список отчетов:
                    $reports_list = [];
                    foreach($reports_conf as $report_name => $report_value) {
                        $reports_list[$report_name] = $report_value['title'];
                    }
                    
                    
                    switch ($report_type) {
                        case 'common':
                            $periodStats = $stats->getFeedStatData($report_type, $feed_id_list, $dates, $report_conf);
                            //$campaignStats = $statsDaysModel->getStatsByFeeds($feed_id_list, $dates);
                            break;
                        case 'transactions':
                            $periodStats = $stats->getFeedStatData($report_type, $feed_id_list, $dates, $report_conf);
                            break;
                        default:
                            $data['error'] = _t('Извините, тип отчета "'. $report_type .'" недоступен');
                            break;
                    }

                    $data['feeds'] = $feeds;
                    $data['current_report'] = $report_type;
                    $data['current_period'] = $current_period;
                    $data['dates'] = $dates;
                    $data['periodStats'] = $periodStats;
                    //$data['campaignStats'] = $campaignStats;
                    $data['report_conf'] = $report_conf;
                    $data['reports_list'] = $reports_list;
                    $data['periods_list'] = $this->container->get('config')['feed_conf']['periods_list'];
                    $data['colors_active_lines'] = $this->container->get('config')['feed_conf']['colors_active_lines'];
                    
                } else {
                    $data['error'] = _t('Извините, у пользователя нет фидов');
                }

            } catch(\Exception $e) {
                $data['error'] = _t('Извините, статистика временно не работает');
            }

            $data = array_merge($data, [
                'lang' => $request->getAttribute('layoutInfo')->getLang(),
                'layoutInfo' => $request->getAttribute('layoutInfo'),
            ]);     

            return new HtmlResponse($this->template->render('app::user/cabinet-feed', $data));
        }
        elseif($request->getAttribute('action') == self::ACTION_CATS)
        {
            try {

                /** @var UserService $auth */
                $auth = $this->container->get(UserService::class);
                $userId = $auth->getIdentity()->getId();
                
                /** @var \App\Model\Feeds\Shops $shopsModel */
                $shopsModel = $this->container->get(\App\Model\Feeds\Shops::class);
                $shop = $shopsModel->findOne(['users_id' => $userId]); // Пока считаем, что у фида один магазин
                
                if($shop) {
                    
                    $shop_id = $shop->getId();

                    // Определяем список фидов магазина:
                    /** @var \App\Model\Feeds\Feeds $shopFeedsModel */
                    $shopFeedsModel = $this->container->get(\App\Model\Feeds\ShopFeeds::class);
                    $shopFeeds = $shopFeedsModel->findAll(['shop_id' => $shop_id]) -> toArray();
                    
                    if (count($shopFeeds) > 0) {
                    
                        /** @var \App\Model\ShopFeeds $shopFeedsModel */
                        $feedsModel = $this->container->get(\App\Model\Feeds\Feeds::class);
                        /** @var \App\Model\Feeds\Categories $categoriesModel */
                        $categoriesModel = $this->container->get(\App\Model\Feeds\Categories::class);
                        /** @var \App\Model\Feeds\CategoryFees $categoryFeesModel */
                        $categoryFeesModel = $this->container->get(\App\Model\Feeds\CategoryFees::class);
                        
                        // Формируем древовидную структуру категорий:
                        function get_sub_cats($id, $cats, $parent_cat_percent, $fees) {
                            $sub_cats=[];
                            foreach ($cats as $cat) {
                                if ($cat['parentid'] == $id) {

                                    $cat_percent = $cat['orderpercent'];
                                    $is_own = 1;
                                    if ($cat_percent < 0) {

                                        if ($fees[$cat['id']]) {
                                            $cat_percent = $fees[$cat['id']];
                                        } else {
                                            $cat_percent = $parent_cat_percent;
                                            $is_own = 0;
                                        }

                                    }

                                    $cat['own'] = $is_own;
                                    $cat['percent'] = $cat_percent/10;
                                    $cat['sub_cats'] = get_sub_cats($cat['id'], $cats, $cat_percent, $fees);
                                    $sub_cats[] = $cat;
                                }
                            }
                            return $sub_cats;
                        }

                        // Определяем список категорий у фидов магазина:
                        $feeds_cats = [];
                        foreach ($shopFeeds as $shopFeed) {

                            $feed_id = $shopFeed['feed_id'];
                            $feed = $feedsModel->findOne(['id' => $feed_id]);
                            $feed_title = $feed->getTitle();
                            $feed_percent = $feed->getOrderpercent();

                            // fees категорий фида:
                            $feed_category_fees = $categoryFeesModel->findAll(['FeedID' => $feed_id]) -> toArray();
                            $fees = [];
                            foreach ($feed_category_fees as $feed_category_fee) {
                                $fees[$feed_category_fee['catid']] = $feed_category_fee['orderpercent'];
                            }

                            // Определяем список категорий фида:
                            $cats_list = $categoriesModel->findAll(['FeedID' => $feed_id], 'Title ASC') -> toArray();

                            $feed_cats = [];
                            foreach ($cats_list as $cat) {
                                if ($cat['parentid'] == 0) {

                                    $cat_percent = $cat['orderpercent'];
                                    $is_own = 1;
                                    if ($cat_percent < 0) {
                                        if ($fees[$cat['id']]) {
                                            $cat_percent = $fees[$cat['id']];
                                        } else {
                                            $cat_percent = $feed_percent;
                                            $is_own = 0;
                                        }
                                    }

                                    $cat['own'] = $is_own;
                                    $cat['percent'] = $cat_percent/10;
                                    $cat['sub_cats'] = get_sub_cats($cat['id'], $cats_list, $cat_percent, $fees);
                                    $feed_cats[] = $cat;
                                }
                            }

                            $feeds_cats[] = array(
                                'id' => $feed_id,
                                'title' => $feed_title,
                                'percent' => $feed_percent/10,
                                'cats' => $feed_cats,
                            );

                        }

                        // Список отчетов:
                        $reports_list = [];
                        $reports_conf = $this->container->get('config')['feed_conf']['reports'];
                        foreach($reports_conf as $report_name => $report_value) {
                            $reports_list[$report_name] = $report_value['title'];
                        }
                        
                        $data['lang'] = $request->getAttribute('layoutInfo')->getLang();
                        $data['feeds_cats'] = $feeds_cats;
                        $data['reports_list'] = $reports_list;
                        
                    } else {
                        $data['error'] = _t('Извините, у магазинов пользователя нет фидов ');
                    }

                } else {
                    $data['error'] = _t('Извините, у пользователя нет магазина');
                }

            } catch(\Exception $e) {
                $data['error'] = _t('Извините, категории временно не доступны');
            }
            
            $data = array_merge($data, [
                'lang' => $request->getAttribute('layoutInfo')->getLang(),
                'layoutInfo' => $request->getAttribute('layoutInfo'),
            ]);     

            return new HtmlResponse($this->template->render('app::user/cabinet-cats', $data));
        }    
        
    }
    
    private function getStatData(ServerRequestInterface $request) 
    {
        /** @var UserService $auth */
        $auth = $this->container->get(UserService::class);
        $userId = $auth->getIdentity()->getId();
        
        /** @var \App\Model\Statistics $stats */
        $stats = $this->container->get(Statistics::class);
        
        // Выводим стр. по фидам, если за пользователем закреплен фид:
        /** @var \App\Model\Feeds $feedsModel */
        $feedsModel = $this->container->get(Feeds::class);
        $feeds = $feedsModel->findAll(['clientid' => $userId])->toArray();
        
        // Фиды пользователя:
        $feed_id_list = [];
        foreach($feeds as $feed_item) {
            $feed_id = $feed_item['id'];
            if (!in_array($feed_id, $feed_id_list)) {
                $feed_id_list[] = $feed_id;
            }
        }         
        
        $report_type = $request->getAttribute('report');
        $data_request = $request->getParsedBody();
        $dates = $data_request['period'];
        
        $report_conf = $this->container->get('config')['feed_conf']['reports'][$report_type];
        
        switch ($report_type) {
            case 'common':
                $periodStats = $stats->getFeedStatData($report_type, $feed_id_list, $dates, $report_conf);
                //$campaignStats = $statsDaysModel->getStatsByFeeds($feed_id_list, $dates);
                break;
            case 'transactions':
                $periodStats = $stats->getFeedStatData($report_type, $feed_id_list, $dates, $report_conf);
                break;
            default:
                $periodStats = null;
                $campaignStats = null;
                break;
        }
        
        if (!$periodStats) {
            return new JsonResponse(null);
        }
        
        /*
        if ($periodStats || $companyStats) {
            $data = array(
                'period' => $periodStats,
                'campaign' => $campaignStats,
            );
        } else {
            $data = null;
        }
        */
        
        $data = $periodStats;
        
        return new JsonResponse($data);
    }
    
    private function editCatsData(ServerRequestInterface $request)
    {
        $data = $request->getParsedBody();
        $cats = json_decode($data['cats'], true);
        
        $cats_id = array_keys($cats);
        
        /** @var \App\Model\Feeds\CategoryFees $categoryFeesModel */
        $categoryFeesModel = $this->container->get(\App\Model\Feeds\CategoryFees::class);
        
        /** @var DelegatingHydrator $hydrator */
        $hydrator = $this->container->get(DelegatingHydrator::class);
        
        foreach ($cats_id as $cat) {
            $category_fee = $categoryFeesModel->findOne(['CatID' => $cat]);
            
            if ($category_fee) {
                if ($cats[$cat]['p']) {
                    $category_fee->setOrderpercent($cats[$cat]['p']);
                    $result = $categoryFeesModel->saveRetargCatFee($category_fee, 'update');
                } else {
                    $result = $categoryFeesModel->deleteRetargCatFee($category_fee);
                }
                if(!$result) {
                    throw new \Exception('DB error');
                }
            } else {
                $cat_item = $cats[$cat];
                $data = array(
                    'feedid' => $cat_item['fi'],
                    'catid' => $cat_item['id'],
                    'foreigncatid' => $cat_item['fc'],
                    'orderpercent' => $cat_item['p']
                );
                $categoryFee = $hydrator->hydrate($data, new CategoryFee());
                $result = $categoryFeesModel->saveRetargCatFee($categoryFee, 'insert');
                if(!$result) {
                    throw new \Exception('DB error');
                }
            }
        }
        
        $response = new JsonResponse([
            'result' => true,
            'redirect' => $this->router->generateUri('user.cabinet.cats', [
                'lang' => $request->getAttribute('layoutInfo')->getLang(),
            ])
        ]);
        return $response;
    }
}