<?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;

require_once 'BaseModel.php';

/**
 * Pixelcms_articles model.
 *
 * @package  pixelcms_articles
 * @since    1.0
 */
class Pixelcms_articlesModelPixelcms_articles extends BaseModel
{
    protected $api_endpoint;
    protected $module;
    protected $articleId;
    protected $category_id;
    protected $cms_url;
    protected $alias;
    protected $filter;
    protected $api_version;
	protected $state;
	protected $limit;
	protected $page;

	protected $defaults = [
		'cut_images' => 1,
		'image_fallback' => 1,
        'disable_title_image' => 0,
        'show_date' => 'before',
        'intro_length' => 200,
	];

    public function __construct(array $config = array())
    {
        parent::__construct($config);

        /** @var extendedRegistry $params - Settings for current Menu Item */
        $params = $this->getState('params');

        // echo '<pre>'.print_r($params, true).'</pre>';

        $this->limit = $params->getInt('limit', 5);
        $this->page = $params->getInt('page', 0);
        $this->category_id = $params->getInt('pixelcms_category_id');
        $this->articleId = $params->getInt('articleId', null);
        $this->filter = $params->get('pixelcms_filter', 'active');

        $this->alias = $params->get('pixel_cms_alias');
        $this->cms_url = $params->get('pixel_cms_url');
        $this->api_version = $params->get('pixel_cms_version');
        $this->api_endpoint = 'articles';
        $this->module = "pixelcms_articles";
    }

    public function getArticle()
    {
        return $this->filterArticles($this->getCachedArticles());
    }

    private function filterArticles($articles)
    {
        // Already Filtered
        if (is_object($articles)) {
            if ($articles->id !== $this->articleId) return [];
            return $articles;
        }

        if ($this->category_id) {
            $articles = array_filter($articles, function ($article) {
                return ($article->category->id === $this->category_id);
            });
        }
        if ($this->articleId) {
            if (is_array($this->articleId)) {
                if (in_array("", $this->articleId)) return $articles;
                $articles =  array_filter($articles, function ($article) {
                    return in_array($article->id, $this->articleId);
                });
            } else {
                $articles = array_reduce($articles, function ($carry, $article) {
                    if ($article->id == $this->articleId) {
                        $carry = $article;
                    }
                    return $carry;
                });
            }
        }

        return $articles;
    }

    public function getCategory()
    {
        $data = $this->getCachedCategory();
        if ($this->category_id) {
            return array_reduce($data, function ($carry, $category) {
                if ($category->id === $this->category_id) {
                    $carry = $category;
                }
                return $carry;
            });
        }
        return $data;
    }

    private function getCachedArticles()
    {
        $cached = json_decode($this->cache->get('articles', $this->module));

        // No Cache found generate one
        if (empty($cached)) {
            $articles = $this->extendCache(json_decode($this->getData()), $cached);
        } else if (empty($filtered = $this->filterArticles($cached))) {
            $articles = $this->extendCache(json_decode($this->getData()), $cached);
        }

        return $this->limitArticles($articles ?? $filtered);
    }

    private function limitArticles($articles)
    {
        if ($this->limit > 0) {
            return array_slice($articles, $this->page * $this->limit, $this->limit);
        }
        return $articles;
    }

    private function merge_two_arrays($array1,$array2)
    {
        $merged_keyed = array_column(array_merge($array1,$array2), NULL, 'id');
        ksort($merged_keyed);
        return array_values($merged_keyed);
    }

    private function extendCache($newCache, $oldCache)
    {
        $newCache = is_object($newCache) ? [$newCache] : $newCache;
        $cache = empty($oldCache) ? $newCache : $this->merge_two_arrays($oldCache, $newCache);

        $this->cache->store(json_encode($cache), 'articles', $this->module);
        return $cache;
    }

    public function getCachedCategory()
    {
        $categories = $this->cache->get('categories', $this->module);

        if (empty($categories)) {
            $categories = $this->getCategories();
            $this->cache->store($categories, 'categories', $this->module);
        }

        return json_decode($categories);
    }

    private function getData()
    {
        $parameters = [];

        if ($this->category_id) {
            $parameters['category'] = $this->category_id;
        }

        $url = $this->cms_url . '/api/' . $this->api_version . '/' . "$this->api_endpoint/$this->filter";

        if ($this->filter === 'all') {
            $url = $this->cms_url . '/api/' . $this->api_version . '/' . "$this->api_endpoint";
        }

        if ($this->articleId) {
            $url = $this->cms_url . '/api/' . $this->api_version . '/' . "$this->api_endpoint/$this->articleId";
        }

        return $this->cURL($url, $parameters);
    }

    private function getCategories()
    {
        $parameters = [];

        $url = $this->cms_url . '/api/' . $this->api_version . '/' . "categories";

        return $this->cURL($url, $parameters);
    }
}
