<?php

namespace dominion\api;

use GraphQL\Type\Definition\Type;

class GraphQLPagination
{
    public $parentRoot;
    public $page = 1;
    public $perPage = 25;
    public $offset = 0;
    public $totalCount = 0;
    public $pageCount = 0;
    public $currentPage = 0;
    public $sort = '';
    public $data = [];
    public $addArgs = [];


    public static $arPrefix = [
        '<' => 'lt',
        '>' => 'gt',
        '<=' => 'lte',
        '>=' => 'gte',
        '!=' => 'neq',
        'IN' => 'in',
        'NOT IN' => 'nin',
      //  'LIKE' => 'like',
    ];

    public function setMeta($totalCount, $perPage)
    {
        $this->totalCount = $totalCount - $this->offset;
        $this->perPage = $perPage;
        $this->currentPage = $this->page;
        $this->pageCount = ceil($this->totalCount/ $this->perPage);
    }

    public function setMetaByQuery($query)
    {
        $this->setMeta($query->count(), $this->perPage);
    }


    public function andWhere($query, $params, $fields, $prefix = '')
    {
        $prefix = empty($prefix) ? '' : ($prefix . '.');
        foreach($fields as $item)
        {
            if(isset($params[$item]))
            {
                $query->andWhere([$prefix . $item => is_bool($params[$item]) ? (int)$params[$item] : $params[$item]]);
            }
            foreach (self::$arPrefix as $key => $pref)
            {
                $newKey = "{$pref}_{$item}";
                if(isset($params[$newKey]))
                {
                    $query->andWhere([$key, $prefix . $item, $params[$newKey]]);
                }
            }
        }
        return $query;
    }

    public function andWhereLike($query, $params, $fields, $prefix = '')
    {
        $prefix = empty($prefix) ? '' : ($prefix . '.');
        foreach($fields as $item)
        {
            if(isset($params[$item]))
            {
                $query->andWhere(['like', $prefix . $item, $params[$item]]);
            }
        }
        return $query;
    }

    public function orderBy($query, $params, $fields, $sortParam = 'sort', $prefix = '')
    {
        $prefix = empty($prefix) ? '' : ($prefix . '.');
        $sort = isset($params[$sortParam]) ? $params[$sortParam] : (isset($params['in_'.$sortParam]) ? $params['in_'.$sortParam] : []);
        if(!empty($sort))
        {
            $sort = is_array($sort) ? $sort : (array)$sort;
            $orderBy = [];
            foreach($sort as $item)
            {
                $value = explode('_', $item);
                if(count($value) == 2 && in_array($value[0], $fields) && in_array($value[1], ['asc', 'desc']))
                {
                    $orderBy[$prefix . $value[0]] =  $value[1] == 'asc' ? SORT_ASC : SORT_DESC;
                }
                elseif($item == 'rand')
                {
                    $orderBy['RAND()'] =  SORT_ASC;
                }
            }
            if(!empty($orderBy))
            {
                $query->orderBy($orderBy);
            }

        }
        return $query;
    }

    public function getItemsByPage($query)
    {
        $offset = $this->perPage * ($this->page -1);
        $offset += $this->offset;
        return $query->limit($this->perPage)->offset($offset)->all();
    }

    public static function argumentModify($args = [])
    {
        foreach ($args as $key=> $value)
        {
            if(isset($value['type']) && /*in_array($value['type'], [Type::int()]) &&*/ isset($value['modify']) && $value['modify'])
            {
                $arPrefix = isset($value['modifyOption']) ? (array)$value['modifyOption'] : self::$arPrefix;
                if(str_replace($arPrefix, '', $key) == $key)
                {
                    foreach ($arPrefix as $prefix)
                    {
                        $newKey = "{$prefix}_{$key}";
                        if (!isset($args[$newKey]))
                        {
                            $args[$newKey] = $value;
                            if(in_array($prefix, ['in', 'nin']))
                            {
                                $args[$newKey]['type'] = Type::listOf($args[$newKey]['type']);
                            }
                        }
                    }
                }
            }
        }
        return $args;
    }


}