<?php
/**
 * @package DJ-Catalog2-Yootheme
 * @copyright Copyright (C) DJ-Extensions.com, All rights reserved.
 * @license http://www.gnu.org/licenses GNU/GPL
 * @author url: http://dj-extensions.com
 * @author email contact@dj-extensions.com
 */

namespace DJExtensions\DJCatalog2\YOOtheme\Builder\Source;
defined('_JEXEC') or die;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Factory;
use Joomla\CMS\Session\Session;
use Joomla\CMS\User\User;
use YOOtheme\Builder;
use YOOtheme\Config;
use YOOtheme\Http\Request;
use YOOtheme\Http\Response;
use YOOtheme\Builder\Joomla\ContentListener;
use DJExtensions\DJCatalog2\YOOtheme\Builder\Source\ProducerListener;
class ItemListener
{
	const PATTERN = '/^<!-- (\{.*\}) -->/';

	/**
	 * @var User
	 */
	protected $user;

	public function prepareContent(Config $config, CMSApplication $application, Session $session, Builder $builder, $event)
	{
		list($item, $params) = $event->getArguments();
		static $first = true;
		if (!$first || !static::isItemView()) {
			return;
		}
		// Make sure this is executed only once
		$first = false;
		$type = '';
		if ($this->user) {
			$session->set('user', $this->user);
		}

		if(isset($item->product_layout)) {
			$content = preg_match(self::PATTERN, $item->product_layout, $matches) ? $matches[1] : null;
			$type = 'product';
		}
		else if(isset($item->producer_layout)) {
			$content = preg_match(self::PATTERN, $item->producer_layout, $matches) ? $matches[1] : null;
			$type = 'producer';
		}
		else $content = '';


		if ($config('app.isCustomizer')) {

			if ($page = $config('req.customizer.page')) {
				if ($item->id === $page['id']) {
					$content = !empty($page['content']) ? json_encode($page['content']) : null;
				} else {
					unset($page);
				}
			}

			$modified = !empty($page);
			$config->add('customizer.page', [
				'id' => $item->id,
				'title' => $item->name,
				'content' => $content ? $builder->load($content) : $content,
				'modified' => $modified,
				'collision' => $this->getCollisionInfo($item),
			]);

		}
		if ($content) {
			if($type == 'product') {
				// Render builder output
				$item->product_layout = $builder->render($content, [
					'prefix' => 'page',
					'item' => $item,
				]);
			}else if ($type == 'producer') {
				$item->producer_layout = $builder->render($content, [
					'prefix' => 'page',
					'item' => $item,
				]);
			}

			// Used to determine active builder layout in html/helpers.php
			$config->set('app.isBuilder', true);
		}
	}

	public static function loadTemplate(Config $config, $event)
	{
		if (!$config('app.isBuilder')) {
			return;
		}
		list($view) = $event->getArguments();

		$layout = $view->getLayout();

		$context = $view->get('context');

		if (($context !== 'com_djcatalog2.item' || $context !== 'com_djcatalog2.producer') || $layout !== 'default') {
			return;
		}


		$item = $view->get('item');
		if($context === 'com_djcatalog2.item')
			$content = $item->product_layout;
		else $content = $item->producer_layout;

		$view->set('_output', $content);
	}

	public function savePage(Request $request, Response $response, Builder $builder)
	{
		$request->abortIf(!$page = $request('page'), 400)
			->abortIf(!$page = base64_decode($page), 400)
			->abortIf(!$page = json_decode($page), 400);
		if($page->contextView == 'com_content.article'){
			$contentListener = new ContentListener();
			$contentListener->savePage($request,$response,$builder);
			return $response->withJSON([
				'com_content.article' => '1',
			]);
		}
		if($page->contextView == 'com_djcatalog2.producer'){
			$producerListener = new ProducerListener();
			$producerListener->savePage($request, $response, $builder);
			return $response->withJSON([
				'com_djcatalog2.producer' => '1',
			]);
		}
		\JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_djcatalog2/tables');
		if (!class_exists('DJCatalog2ImageHelper')) {
			require_once JPATH_ADMINISTRATOR . '/components/com_djcatalog2/helpers/image.php';
		}
		if (!class_exists('DJCatalog2TableItems')) {
			require_once JPATH_ADMINISTRATOR . '/components/com_djcatalog2/tables/items.php';
		}
		if (!class_exists('DJCatalog2ModelItem')) {
			require_once JPATH_ADMINISTRATOR . '/components/com_djcatalog2/models/item.php';
		}

		$model = new \Djcatalog2ModelItem(['ignore_request' => true]);
		$item = $model->getItem((int)$page->id); // $page->page->id is item's id
		$data = [
			'id' => $page->id,
			'product_layout' => '',
			'alias' => $item->alias
		];
		if ((array) $page->content) {
			if(!isset($page->content->type)){
				$content = '';
				$data['product_layout'] = '';
			}else {
				$content = json_encode($page->content);
				$fulltext = json_encode($builder->withParams(['context' => 'save'])->load($content));
				$data['product_layout'] = "<!-- {$fulltext} -->";
			}

		}

		// JPATH_COMPONENT constant isn't set yet
		if (!defined('JPATH_COMPONENT')) {
			define('JPATH_COMPONENT', JPATH_BASE . '/components/com_ajax');
		}

		$request->abortIf(!$this->allowEdit($item), 403, 'Insufficient User Rights.');

		$collision = self::getCollisionInfo($item);

		$model->save($data);

		// reload article after save
		$item = $model->getItem($page->id);

		return $response->withJSON([
			'id' => $page->id,
			'collision' => self::getCollisionInfo($item),
		]);
	}

	protected static function getCollisionInfo($item)
	{
		$user = Factory::getUser($item->created_by);
		$modifiedBy = $user ? $user->username : '';
		if(isset($item->product_layout))
			return [
				'contentHash' => md5($item->product_layout . $item->description),
				'modifiedBy' => $modifiedBy,
			];
	}

	protected function allowEdit($item)
	{
		$user = Factory::getUser();
		$asset = "com_djcatalog2.item.{$item->id}";

		return $user->authorise('core.edit', $asset)
			|| $user->authorise('core.edit.own', $asset)
			&& $user->get('id') == $item->created_by;
	}

	protected function isItemView() {
		$input = Factory::getApplication()->input;


		return $input->getCmd('option') === 'com_djcatalog2' && ($input->getCmd('view') === 'item' || $input->getCmd('view') === 'producer') && is_null($input->getCmd('task'));
	}
}
