<?php

namespace Widgets\Jquery\Jgrid;

use Core\Exceptions\IsJsonResponce;
use Core\Repository\PropelQueryAbstract;
use Propel\Runtime\ActiveQuery\BaseModelCriteria;
use Propel\Runtime\ActiveQuery\Criteria;
use Propel\Runtime\ActiveQuery\Exception\UnknownColumnException;
use Propel\Runtime\ActiveRecord\ActiveRecordInterface;
use Propel\Runtime\Map\TableMap;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * Description of RepoJGrid
 *
 * @author Dmitriy
 */
class RepoJGrid extends ActiveJGrid
{

    private $beforSelectFn;

    protected $post = [];

    protected $summary = [];

    protected $summary_result = [];

    protected $onclick_href = true;


    protected $customFilter;


    function __construct(PropelQueryAbstract $repository, $template, $twig)
    {

        parent::__construct($template, $twig);

        //$this->setSession($session);
        $this->model = $repository->getQuery();

        $this->name = 'registry_' . get_class($this->model);

        if ($post = $this->loadStateParams()) {
            $this->post = $post;
        } else {
            //сохранение данных сортировки
            $this->saveStateParams($this->post);
        }
    }

    /**
     * @param mixed $customFilter
     * @return RepoJGrid
     */
    public function setCustomFilter($customFilter)
    {
        $this->customFilter = $customFilter;
        return $this;
    }


    /**
     * @param string $view
     * @return string
     * @throws \ReflectionException
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    public function Render($view = 'default')
    {

        //отправка данные если аякс
        if ($this->ajax_query() === true) {

            throw  new IsJsonResponce(new JsonResponse($this->getJsonData()));
        }

        return parent::Render($view);
    }

    /**
     *
     */
    protected function getJsonData()
    {

        //$this->applyFilter($this->model);

        $count = $this->getCount();

        $rows = $this->post['rows'];
        $page = $this->post['page'];

        if ($count > 0) {
            $total = ceil($count / $rows);
        } else {
            $total = 0;
        }
        if ($page > $total)
            $page = $total;

        //формируем данные
        $responce = array();
        $responce['page'] = $page;
        $responce['total'] = $total;
        $responce['records'] = $count;
        //Получаем данные
        $responce['rows'] = $this->getRows();

        if (count($this->summary) > 0) {
            foreach ($this->summary as $summ_field) {
                $responce['userdata'][$summ_field] = number_format($this->summary_result[$summ_field],
                    2, '.', ' ');
            }
        }

        return $responce;
    }


    protected function getCount()
    {

        $Model = $this->model;

        if ($this->beforSelectFn) {
            $Model = call_user_func($this->beforSelectFn, $Model);
        }
        return $Model->count();
    }

    /**
     * получение данных
     * @return type
     */
    protected function getRows()
    {

        $Model = $this->model;

        if (isset($this->post['sidx']) && isset($this->post['sord'])) {
            $_order = "orderBy" . $this->post['sidx'];
            $_type = strtoupper($this->post['sord']) == 'DESC' ? Criteria::DESC : Criteria::ASC;
        } else {
            $_order = "orderBy" . $this->sortname;
            $_type = strtoupper($this->sortorder) == 'DESC' ? Criteria::DESC : Criteria::ASC;
        }

        try{
            $Model->$_order($_type);
        }
        catch (UnknownColumnException $ex){
        }
        
        $Model = $this->setExtendsFilter2($Model);

        if ($this->beforSelectFn) {
            $Model = call_user_func($this->beforSelectFn, $Model);
        }

        //dump($Model);

        if (isset($this->post['page']) && isset($this->post['rows'])) {
            $rows = $Model->paginate((int)$this->post['page'], $this->post['rows']);
        } else {
            $rows = $Model->limit($this->post['rows'])->find();
        }


        $line = [];

        foreach ($this->columns as $k => $column) {
            $line[] = '$this->prepareRow3($Entity,\'' . $column['name'] . '\',\'' . $column['index'] . '\') '; //
        }

        $this->line = '$_rows[$i] = array( \'id\' => $this->prepareFirstRow($Entity),  \'cell\' => array(' . "\r\n" . implode(',' . "\r\n",
                $line) . '));';

        return $this->extractRows($rows);
    }

    /**
     * Применение фильтра с клиента
     * @param \SimpleORM\Specification $criteria
     */
    protected function setExtendsFilter2(BaseModelCriteria $Model)
    {

        if(is_callable($this->customFilter)){
            return call_user_func($this->customFilter,$Model,$this->columns);
        }

        $where = [
        ];

        foreach ($this->columns as $column) {

            if (input_post($column['index'])) {
//                $where[$column['index']] = [
//					'value'	=>	input_post($column['index']),
//					'operator'=>'like'
//				];
                $_filter = 'filterBy' . $column['index'];

                $filterValue = input_post($column['index']) . '%';

                $Model->$_filter($filterValue, Criteria::LIKE );
            }
        }

        //$criteria->setWhere($where);
        return $Model;
    }

    protected function extractRows($rows)
    {
        $summ_text = '';

        $this->customformat = array_change_key_case($this->customformat);
        $this->summary_result = array_change_key_case($this->summary_result);

        if (count($this->summary) > 0) {
            foreach ($this->summary as $summ_field) {
                $this->summary_result[$summ_field] = 0;
                $summ_text .= '$this->summary_result[\'' . $summ_field . '\'] += $this->prepareRow3($Entity,\'' . $summ_field . '\',\'' . $summ_field . '\');';
            }
        }
        //	ed($summ_text,1);
        $_rows = array();

        $i = 0;

        if (count($rows) > 0) {
            foreach ($rows as $Entity) {

                $row = array_change_key_case($Entity->toArray(TableMap::TYPE_PHPNAME));

                if (!empty($row[key($row)])) {
                    eval($this->line);

                    if ($summ_text > '')
                        eval($summ_text);

                    $i++;
                }
            }
        }

        return $_rows;
    }

    protected function prepareFirstRow($Entity)
    {
        $row = $Entity->toArray();
        return $row[key($row)];
    }

    protected function prepareRow3(ActiveRecordInterface $Entity,
                                   $field,
                                   $alias)
    {

        $field = strtolower($field);

        $row = array_change_key_case($Entity->toArray(TableMap::TYPE_PHPNAME));

        $result = isset($row[$field]) ? $row[$field] : nbs();

        if (isset($this->customformat[$field])) {
            $result = call_user_func($this->customformat[$field], $Entity);
        }
////echo $field;
//        //суммируем результат
//        if (isset($this->summary[$field])) {
//            //echo $result;
//            $this->summary[$field] += (float) strip_tags($result);
//        }

        return $result;
    }

    protected function applyFilter($model)
    {

    }

    /**
     * Пользовательская функция для выборки данных
     * @param type $fn
     */
    function beforSelectFn($fn)
    {
        $this->beforSelectFn = $fn;
        return $this;
    }

    public function setMultiselect(bool $value)
    {
        $this->multiselect = $value;
        return $this;
    }
}
