<?php

namespace Velis;

use Velis\Model\DataObject;
use Velis\Model\Cacheable;
use Velis\Lang;
use Velis\Db\Exception as DbException;

/**
 * Saved queries
 * @author Paweł Robaczewski <pr@velis.pl>
 */
class Query extends DataObject implements Cacheable
{
    const TYPE_JSON = 'json';

    /**
     * List sort options
     */
    const ORDER_NAME = 'name';


    /**
     * Default list order
     * @var string
     */
    protected static $_listDefaultOrder = self::ORDER_NAME;



    /**
     * Returns related sql table
     * @return string
     */
    protected function _getTableName()
    {
        return 'app.query_tab';
    }


    /**
     * Returns customer name
     * @return string
     */
    public function getName()
    {
        return $this['name'];
    }


    /**
     * Get full url the query points to
     *
     * @return \Velis\Query
     */
    public function getFullUrl()
    {
        $url = '/' . $this['module'] . '/' . $this['controller'] . '/' . $this['action'] . '?';
        $url .= $this['query'];
        return $url;
    }


    /**
     * List queries for current page and logged-in user
     *
     * @return \Velis\Query[]
     */
    public static function getListForPage($module, $controller, $action, $mobile = false)
    {
        $queries = self::listCached();

        foreach ($queries as $key => $query) {
            if ($query['user_id'] != App::$user->id()) {
                unset($queries[$key]);
                continue;
            }

            if (
                $query['module']     != $module ||
                $query['controller'] != $controller ||
                $query['action']     != $action
            ) {
                unset($queries[$key]);
                continue;
            }

            if ($mobile !== (bool) $query['mobile']) {
                unset($queries[$key]);
                continue;
            }
        }

        return $queries;
    }


    /**
     * List queries for current page and logged-in user
     *
     * @return \Velis\Query[]
     */
    public static function getListForCurrentPage($mobile = false)
    {
        return static::getListForPage(
            App::$registry['moduleName'],
            App::$registry['controllerName'],
            App::$registry['actionName'],
            $mobile
        );
    }


    /**
     * Adds new query
     */
    public function add($updateObjectId = false)
    {
        $this['user_id'] = App::$user->id();

        // $this['query'] in new API (where $this['type'] === 'json) contains JSON strong value
        if ($this['type'] !== 'json') {
            $this->_sanitizeQuery();
        }

        try {
            return parent::add($updateObjectId);
        } catch (Exception $e) {
            if ($e instanceof DbException && $e->getCode() == 23505) {
                throw new Exception(Lang::get('GENERAL_QUERY_EXISTS'));
            }
        }
    }


    /**
     * Clears empty and unwanted attributed from the query string
     */
    protected function _sanitizeQuery()
    {
        $elements = explode('&', $this['query']);

        foreach ($elements as $key => $value) {
            list($paramName, $paramValue) = explode('=', $value);

            if ($paramName == 'page' || (empty($paramValue) && $paramValue !== '0')) {
                unset($elements[$key]);
            }
        }
        $this['query'] = implode('&', $elements);
    }


    /**
     * Removes a query
     * @return bool
     */
    public function remove()
    {
        return parent::_remove();
    }
}
