<?php
/**
 * @package DJ-Events
 * @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
 * @developer Szymon Woronowski - szymon.woronowski@design-joomla.eu
 *
 */

defined('_JEXEC') or die('Restricted access');

use Joomla\Utilities\ArrayHelper;
use Joomla\CMS\CMSObject;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;


jimport('joomla.application.component.modellist');

class DJEventsModelEvents extends JModelList
{
    public function __construct($config = array())
    {
        if (empty($config['filter_fields'])) {
            $config['filter_fields'] = array(
                'a.id', 'a.title', 'a.published', 'a.created', 'c.name', 'l.name', 't.start', 't.end', 'u.name', 'featured', 'a.featured'
            );
        }

        parent::__construct($config);
    }

    protected function populateState($ordering = null, $direction = null)
    {
        // List state information.
        parent::populateState('t.start', 'asc');

        // Initialise variables.
        $app = JFactory::getApplication();
        $session = JFactory::getSession();


        $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
        $this->setState('filter.search', $search);

        $state = $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published');
        $this->setState('filter.published', $state);

        $category = $this->getUserStateFromRequest($this->context . '.filter.category', 'filter_category');
        $this->setState('filter.category', $category);

        $city = $this->getUserStateFromRequest($this->context . '.filter.city', 'filter_city');
        $this->setState('filter.city', $city);

        $location = $this->getUserStateFromRequest($this->context . '.filter.location', 'filter_location');
        $this->setState('filter.location', $location);

        $from = $this->getUserStateFromRequest($this->context . '.filter.from', 'filter_from');
        $this->setState('filter.from', $from);

        $to = $this->getUserStateFromRequest($this->context . '.filter.to', 'filter_to');
        $this->setState('filter.to', $to);

        $tag = $app->input->getInt('tag');
        $this->setState('filter.tag', $tag);

        $limit = $this->getUserStateFromRequest($this->context . '.list.limit', 'limit');
        $this->setState('list.limit', $limit);


        /* TODO:
        $featured = $this->getUserStateFromRequest($this->context.'.filter.featured', 'filter_featured');
        $this->setState('filter.featured', $featured);
        */
        // Load the parameters.
        $params = JComponentHelper::getParams('com_djevents');
        $this->setState('params', $params);
    }

    protected function getStoreId($id = '')
    {
        // Compile the store id.
        $id .= ':' . $this->getState('filter.search');
        $id .= ':' . $this->getState('filter.published');
        $id .= ':' . serialize($this->getState('filter.category'));
        $id .= ':' . serialize($this->getState('filter.city'));
        $id .= ':' . serialize($this->getState('filter.location'));
        $id .= ':' . $this->getState('filter.from');
        $id .= ':' . $this->getState('filter.to');
        $id .= ':' . $this->getState('filter.tag');
        $id .= ':' . $this->getState('filter.featured');

        return parent::getStoreId($id);
    }

    protected function getListQuery()
    {
        // Create a new query object.
        $app = JFactory::getApplication();
        $user = JFactory::getUser();
        $db = $this->getDbo();
        $query = $db->getQuery(true);
        $params = JComponentHelper::getParams('com_djevents');

        // Select the required fields from the table.
        $select_default = 't.start, t.start_time, t.end, t.end_time, a.*, uc.name AS editor, c.id as c_id, c.name as category_name, c.alias as category_alias, 
				r.id as r_id, r.name as city_name, r.alias as city_alias, m.image, m.title as thumb_title, m.video,c.icon_bg as color, u.name AS author_name';
        $query->select($this->getState('list.select', $select_default));


        $query->from('#__djev_events_time AS t, #__djev_events AS a');

        // Join over the users for the checked out user.
        $query->join('LEFT', '#__users AS uc ON uc.id=a.checked_out');    // Join over the users for the checked out user.
        $query->join('LEFT', '#__users AS u ON u.id=a.created_by');

        // Join over the users for the author user.
        //$query->join('LEFT', '#__users AS ua ON ua.id=a.created_by');

        // Join over groups
        $query->join('LEFT', '#__djev_cats AS c ON c.id=a.cat_id');

        $query->join('LEFT', '#__djev_cities AS r ON r.id=a.city_id');

        $query->join('LEFT', '#__djev_events_media AS m ON m.event_id=a.id AND m.poster=1');

        $query->where('t.event_id = a.id AND t.exclude = 0');

        if ($params->get('tags_type', 'djevents') == 'joomla') {
            $query->join('LEFT', '(SELECT tx.event_id, GROUP_CONCAT(jt.title) tags FROM #__djev_jtags_xref tx INNER JOIN #__tags jt ON tx.tag_id=jt.id GROUP BY tx.event_id) v ON a.id=v.event_id');
        }
        $query->join('LEFT', '#__djev_locations AS l ON l.id = a.location_id');
        // Join location
        $query->select(array(
            $db->quoteName('l.name', 'location_name'),
            $db->quoteName('l.address', 'location_address'),
            $db->quoteName('lc.name', 'location_city'),
            $db->quoteName('l.post_code', 'location_post_code'),
            $db->quoteName('l.latitude', 'location_latitude'),
            $db->quoteName('l.longitude', 'location_longitude'),
            $db->quoteName('l.city_id', 'location_city_id'),
            $db->quoteName('l.alias', 'location_alias'),
        ));

        $query->join('LEFT', '#__djev_cities AS lc ON lc.id = l.city_id');

        // Filter by search in title.
        $search = $this->getState('filter.search');
        if (!empty($search)) {
            if (stripos($search, 'id:') === 0) {
                $query->where('a.id = ' . (int)substr($search, 3));
            } else {
                $search = $db->quote('%' . $db->escape($search, true) . '%');
                if ($params->get('tags_type', 'djevents') == 'joomla') {
                    $searchCols = array('a.title', 'a.description', 'a.location', 'r.name', 'c.name', 'v.tags');
                } else {
                    $searchCols = array('a.title', 'a.description', 'a.location', 'r.name', 'c.name');
                }
                $query->where('(' . implode(' LIKE ' . $search . ' OR ', $searchCols) . ' LIKE ' . $search . ')');
            }
        }

        $state = $this->getState('filter.published', false);
        if (is_numeric($state)) {
            $query->where('a.published=' . (int)$state);
        } else if ($state == '') {
            $query->where('(a.published = 0 OR a.published = 1)');
        }

        $category = $this->getState('filter.category', false);
        if ($category) {
            if (is_array($category)) {
                ArrayHelper::toInteger($category);
                $query->where('a.cat_id IN (' . implode(',', $category) . ')');
            } else {
                $query->where('a.cat_id=' . (int)$category);
            }
        }

        $onlyOnline = $this->getState('filter.online', false);
        if ($onlyOnline) {
            $query->where('a.online_event = 1');
        }

        $city = $this->getState('filter.city', false);
        $location = $this->getState('filter.location');
        if ($city) {


            if (is_array($city)) {
                ArrayHelper::toInteger($city);
                $query->where('(a.city_id IN (' . implode(',', $city) . ') OR l.city_id IN (' . implode(',', $city) . '))');
            } else {
                if ($city == '-1' || $location == '-1') { // online event
                    $query->where('a.online_event=1');
                } else {
                    $query->where('a.online_event=0');
                    $query->where('( a.city_id=' . (int)$city . ' OR l.city_id = ' . (int)$city . ')');
                }
            }
        }


        if ($location && DJLicense::isPro()) {
            if (is_array($location)) {
                $query->where('a.location_id IN (' . implode(',', $location) . ')');
            } else {
                if ($location == '-1' || $city == '-1') {
                    $query->where('a.online_event=1');
                } else {
                    $query->where('a.location_id =' . (int)$location);
                }
            }
        }


        $tags = $this->getState('filter.tags');
        if(is_countable($tags) && count($tags)) {
            $query->join('INNER', $db->quoteName('#__djev_tags_xref', 'tag') . ' ON tag.event_id = a.id')
                ->where('tag.tag_id IN (' . implode(',', $tags) . ')');
        }

        // set the time range
        //$timezone = new DateTimeZone( JFactory::getUser()->getParam('timezone') );

        $from = $this->getState('filter.from');
        if (!$this->validateDate($from)) $from = 'now';
        if ($from) {
            $date = JFactory::getDate($from);
            //$date->setTimezone($timezone);
            //$app->enqueueMessage("<pre>from: ".print_r($date->toSql(), true)."</pre>");
            $query->where('t.end >= ' . $db->quote($date->toSql()));
        }

        $to = $this->getState('filter.to');
        if (!$this->validateDate($to)) $to = false; //show all future events
        else $to .= ' +1 day';
        if ($to) {
            $date = JFactory::getDate($to);
            //$date->setTimezone($timezone);
            //$app->enqueueMessage("<pre>to: ".print_r($date->toSql(), true)."</pre>");
            $query->where('t.start < ' . $db->quote($date->toSql()));
        }

        $tag = $this->getState('filter.tag', false);
        if ($tag) {
            if ($params->get('tags_type', 'djevents') == 'joomla') {
                $query->innerJoin('#__djev_jtags_xref AS x ON x.event_id=a.id AND x.tag_id=' . $tag);
            } else {
                $query->innerJoin('#__djev_tags_xref AS x ON x.event_id=a.id AND x.tag_id=' . $tag);
            }
        }

        $featured = $this->getState('filter.featured', false);
        if ($featured) {
            $query->where('a.featured=' . (int)$featured);
        }

        $own = $this->getState('filter.own', false);
        if ($own) {
            $query->where('a.created_by=' . (int)$user->id);
        }

        // Add the list ordering clause.
        $orderCol = $this->state->get('list.ordering', 't.start');
        $orderDirn = $this->state->get('list.direction', 'asc');

        $query->order($db->escape($orderCol . ' ' . $orderDirn));

        JPluginHelper::importPlugin('djevents');

        $app = Factory::getApplication();
        $app->triggerEvent('plgOnMyEventsGetListQuery', array(&$this, &$query));

        return $query;
    }

    protected function validateDate($date)
    {
        $d = DateTime::createFromFormat('Y-m-d', $date);
        return $d && $d->format('Y-m-d') === $date;
    }

    public function getCategories()
    {
        $this->_db->setQuery('SELECT id as value, name as text FROM #__djev_cats ORDER BY name ASC');
        $cats = $this->_db->loadObjectList();
        return $cats;
    }

    public function getCities($locationId = 0)
    {


        $query = $this->_db->getQuery(true);
        $query
            ->select(array(
                'c.id as value',
                'c.name as text'
            ))
            ->from($this->_db->quoteName('#__djev_cities', 'c'))
            ->order('c.name ASC');

        if ($locationId) {
            $query->join('INNER', $this->_db->quoteName('#__djev_locations', 'l') . ' ON l.city_id = c.id');
            $query->where('l.id = ' . (int)$locationId);
        }

        $this->_db->setQuery($query);
        $cities = $this->_db->loadObjectList();
        return $cities;
    }

    public function getLocations($cityId = 0)
    {

        $query = $this->_db->getQuery(true);
        $query
            ->select(array(
                'id as value',
                'name as text'
            ))
            ->from($this->_db->quoteName('#__djev_locations'))
            ->order('name ASC');

        if ($cityId) {
            $query->where('city_id = ' . (int)$cityId);
        }

        $this->_db->setQuery($query);
        $locations = $this->_db->loadObjectList();
        return $locations;
    }

}
