<?php
/**
 * @package    pixelcms_articles
 *
 * @author     christophf <your@email.com>
 * @copyright  A copyright
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 * @link       http://your.url.com
 */

use Joomla\Registry\Registry;

defined('_JEXEC') or die;

class extendedRegistry extends Registry {
    public function getInt(string $path, ?int $default = null): ?int
    {
        $value = $this->get($path, null);
        return ($value === null || $value === '') ? $default : intval($value);
    }

    public function has(string $path): bool
    {
        return $this->exists($path);
    }
}

/**
 *
 * @property extendedRegistry $params
 * @since version
 */
class BaseModel extends JModelItem
{
	protected $query;
	protected $input;
	protected $cache;
	protected $params;
	protected $config;
	protected $defaults = [];
    protected static $timeout = 10;

	public function __construct(array $config = array())
	{
        $this->input = JFactory::getApplication()->input;
        $this->config = JComponentHelper::getParams('com_pixelcms_articles');
		$this->cache = new JCache([]);
		$this->cache->setCaching($this->config->get('cache'));

		parent::__construct($config);
	}

    /**
     * @return array|null
     */
    public function getItem($pk = null)
    {
        return $this->_item;
    }

	protected function populateState()
	{
		$app = JFactory::getApplication('site');

		// Load the parameters.
        /** @var Registry $params */
        $params = $app->getParams();
        $query = $this->getQuery();
        $globalParams = JComponentHelper::getParams('com_pixelcms_articles');
        $input = ($this->input) ? $this->input->getArray() : [];

        $this->params = $params = new extendedRegistry(self::mergeStates([], $globalParams->toArray(), $params->toArray(), $query->toArray(), $input));

		$this->setState('params', $params);
	}

    private static function mergeStates(...$states)
    {
        $states = array_map(function($state) {
            return array_filter($state, function($stateValue) {
                return $stateValue !== null;
            });
        }, $states);
        return array_merge(...$states);
	}

	private function getQuery()
	{
		$app = JFactory::getApplication('site');

		if (!$this->query)
		{
		    if ($this->input && $Itemid = $this->input->getInt('Itemid')) {
                $this->query = new Registry(array_merge([], $this->defaults, $app->getMenu()->getItem($Itemid)->query));
            } else {
                $this->query = new Registry(array_merge([], $this->defaults, $app->getMenu()->getActive()->query));
            }
        }

		return $this->query;
	}

    protected function inCollection($search, $collection, $key = 'id') {
        foreach($collection as $obj) {
            if ($obj->{$key} === $search) return true;
        }
        return false;
    }

    protected function cURL($url, $parameters = [])
    {
        $api_token = $this->getState('params')->get('pixel_cms_token');

        // Show all elements if limit is 0 or less
        if (array_key_exists('limit', $parameters) && $parameters['limit'] <= 0) {
            unset($parameters['limit']);
        }

        $query = http_build_query($parameters);

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => "$url?$query",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => self::$timeout,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_POSTFIELDS => "",
            CURLOPT_HTTPHEADER => array(
                "Accept: application/json",
                "Authorization: Bearer $api_token"
            ),
        ));

        $response = curl_exec($curl);
        $err = curl_error($curl);
        $errNo = curl_errno($curl);
        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

        curl_close($curl);

        if ($err) {
            throw new Exception($err, $errNo);
        } else if ($statusCode < 200 || $statusCode >= 300) {
            try {
                $data = json_decode($response, false, 512, JSON_THROW_ON_ERROR);
                throw new Exception($data->message, $statusCode);
            } catch (\JsonException $exception) {
                throw new Exception("Nicht gefunden", $statusCode);
            }
        }

        return $response;
    }
}
