<?php

define('MBQ_PUSH_BLOCK_TIME', 60);    /* push block time(minutes) */

require_once(dirname(__FILE__).'/../mbqFrame/basePush/TapatalkBasePush.php');   //this sentence only used for push feature of native plugin

/**
 * push class

 */
class TapatalkPush extends TapatalkBasePush {
    
    //native properties
    protected $oApp;
    protected $oDb;
    protected $errMsg;  //error message
    protected $oJUser;  //current user object if loged in
    
    //init
    public function __construct() {
        parent::__construct($this);
        
        $this->oApp = JFactory::getApplication();
        $this->oDb = JFactory::getDBO ();
        
        $oJUser = JFactory::getUser();
        if ($oJUser->id) {
            $this->oJUser = $oJUser;
        }
        $this->loadImActive();
        
        $this->loadPushStatus();
      
        $this->siteUrl = JURI::root();
    }
    
    function get_push_slug()
    {
        $query ="SELECT * FROM #__tapatalk_status LIMIT 1";
		$this->oDb->setQuery($query);
		$results = $this->oDb->loadAssocList ();
		if ($this->findDbError()) return false;
		if ($results) {
            return json_decode($results[0]['status_info']);
		} else {
		    return 0;  //default is empty array
		}
    }
    function set_push_slug($slug = null)
    {
        if (is_null($slug)) {
            $data = json_encode($this->slugData);
        } else {
            $this->slugData = $slug;
            $data = json_encode($slug);
        }
        $query ="SELECT count(update_time) as num FROM #__tapatalk_status";
		$this->oDb->setQuery($query);
		$results = $this->oDb->loadAssocList ();
		if ($this->findDbError()) return false;
		if ($results[0]['num'] == 1) {
            $query = "UPDATE #__tapatalk_status SET update_time = ".$this->oDb->quote(time()).", status_info = ".$this->oDb->quote($data);
		} elseif ($results[0]['num'] == 0) {
		    $query = "INSERT INTO #__tapatalk_status (status_info, create_time, update_time) VALUES (".$this->oDb->quote($data).", ".$this->oDb->quote(time()).", ".$this->oDb->quote(time()).")";
		} else {
		    return false;
		}
        $this->oDb->setQuery($query);
        $this->oDb->query ();
        if ($this->findDbError())
            return false;
        else
            return true;
    }
    function doAfterAppLogin($userId = null)
    {
        if (isset($userId) && !empty($userId) && $this->pushStatus) {
            $query ="SELECT count(user_id) as num FROM #__tapatalk_push_user WHERE user_id = ".$this->oDb->quote($userId);
    		$this->oDb->setQuery($query);
			$results = $this->oDb->loadAssocList ();
			if ($this->findDbError()) return false;
			if ($results[0]['num'] == 1) {
                $query = "UPDATE #__tapatalk_push_user SET update_time = ".$this->oDb->quote(time())." WHERE user_id = ".$this->oDb->quote($userId);
			} elseif ($results[0]['num'] == 0) {
			    $query = "INSERT INTO #__tapatalk_push_user (user_id, create_time, update_time) VALUES (".$this->oDb->quote($userId).", ".$this->oDb->quote(time()).", ".$this->oDb->quote(time()).")";
			} else {
			    return false;
			}
            $this->oDb->setQuery($query);
            $this->oDb->query ();
            if (!$this->findDbError()) return true;
        }
        return false;
    }
  
    
    /**
     * load $this->imActive
     *
     * @return Boolean
     */
    protected function loadImActive() {
        if ($this->oJUser && $this->getActiveAppUserIds($this->oJUser->id)) {
            $this->imActive = true;
        } else {
            $this->imActive = false;
        }
    }
    
    /**
     * filter active user id from tapatalk_push_user table
     *
     * @param  Mixed  user id(integer) or user ids(array)
     * @return  Array  return empty array when get error,or return active user ids array
     */
    protected function getActiveAppUserIds($var) {
        if (!is_array($var)) $var = array($var);
        foreach ($var as &$v) {
            $v = $this->oDb->quote($v);
        }
        $inSql = implode (',', $var);
        $query ="SELECT user_id FROM #__tapatalk_push_user WHERE user_id IN ($inSql)";
		$this->oDb->setQuery($query);
		$results = $this->oDb->loadAssocList ();
		if ($this->findDbError()) return array();
		$ret = array();
		foreach ($results as $r) {
		    $ret[] = $r['user_id'];
		}
		return $ret;
    }
    
    /**
     * load $this->pushStatus and $this->pushKey
     */
    protected function loadPushStatus() {
        
        if (JPluginHelper::isEnabled('system', 'tapatalk') && (@ini_get('allow_url_fopen') || function_exists('curl_init'))) {
            $plugin = JPluginHelper::getPlugin('system', 'tapatalk');
            $settings = json_decode($plugin->params);
            if ($settings->tapatalk_push_key) {
                $this->pushKey = $settings->tapatalk_push_key;
            }
            $this->pushStatus = true;
        }
    }
    
    /**
     * judge db error
     *
     * @return  Boolean
     */
    protected function findDbError() {
        if ($this->oDb->getErrorNum ()) {
            $this->errMsg = 'Db error occured.';
            return true;
        }
        return false;
    }
    
  
      
    /**
     * wrap push data before process push
     *
     * @param  Array  $push_data
     */
    protected function push($push_data) {
        if (!empty($push_data)) {
       
            $data = array(
                'url'  => $this->siteUrl,
                'key'  => $this->pushKey,
            );
            $data = array_merge($data, $push_data);
            self::do_push_request($data);
        }
    }
    
   
    /**
     * thank push
     *
     * @param  Array  $p
     * @return Boolean
     */
    protected function doPushThank($p) {
        $push_data = array();
        if (defined('MBQ_IN_IT') && MBQ_IN_IT) {    //mobiquo
            if ($p['oMbqEtForumPost'] && $p['oMbqEtThank']) {
                $pushPack = array(
                    'userid'    => $p['oMbqEtForumPost']->postAuthorId->oriValue,
                    'type'      => 'thank',
                    'id'        => $p['oMbqEtForumPost']->topicId->oriValue,
                    'subid'     => $p['oMbqEtForumPost']->postId->oriValue,
                    'title'     => $p['oMbqEtForumPost']->postTitle->oriValue,
                    'authorid'  => $this->getPushAuthorId(),
                        'dateline'  => time(),
                        'author_ip' => self::getClientIp(),
                        'author_ua' => self::getClienUserAgent(),
                        'author_type' => $this->check_return_user_type(),
                        'from_app' => self::getIsFromApp(),
                );
                $push_data[] = $pushPack;
                $this->push($push_data);
            }
        } else {    //native plugin
            if ($p['oKunenaForumMessage']) {
                $pushPack = array(
                    'userid'    => $p['oKunenaForumMessage']->userid,
                    'type'      => 'thank',
                    'id'        => $p['oKunenaForumMessage']->thread,
                    'subid'     => $p['oKunenaForumMessage']->id,
                    'title'     => $p['oKunenaForumMessage']->subject,
                      'authorid'  => $this->getPushAuthorId(),
                        'dateline'  => time(),
                        'author_ip' => self::getClientIp(),
                        'author_ua' => self::getClienUserAgent(),
                        'author_type' => $this->check_return_user_type(),
                        'from_app' => self::getIsFromApp(),
                );
                $push_data[] = $pushPack;
                $this->push($push_data);
            }
        }
        return false;
    }
  
    /**
     * newtopic push(include some types push)
     *
     * @param  Array  $p
     * @return Boolean
     */
    protected function doPushNewtopic($p) {
        $push_data = array();
        if (defined('MBQ_IN_IT') && MBQ_IN_IT) {    //mobiquo
            $topicId = $p['oMbqEtForumTopic']->topicId->oriValue;
            $forumId = $p['oMbqEtForumTopic']->forumId->oriValue;
        } else {    //native plugin
            $topicId = $p['oKunenaForumMessage']->thread;
            $forumId = $p['oKunenaForumMessage']->catid;
        }
        $db = JFactory::getDBO ();
		$query = "SELECT user_id FROM #__kunena_user_categories WHERE category_id={$db->Quote($forumId)} AND subscribed=1";
		$db->setQuery ( $query );
		$userIds = (array) $db->loadColumn();
		$objsKunenaUser = $this->getUsersByUserIdsExceptMe($userIds);
		$oKunenaForumTopic = $this->getTopicByTopicId($topicId);
		if ($oKunenaForumTopic) {
		    $oKunenaForumMessage = $this->getPostByPostId($oKunenaForumTopic->first_post_id);
		    if ($oKunenaForumMessage) {
                $users = array();
		        foreach ($objsKunenaUser as $oKunenaUser) {
                    $users[] = $oKunenaUser->userid;
		        }
		        //can send push
                $forum = KunenaForumCategoryHelper::getCategories($oKunenaForumMessage->catid);
                $pushPack = array(
                         'type'      => 'newtopic',
                         'userid'        => '',
                       'id'        => $topicId,
                        'subid'     => $oKunenaForumMessage->id,
                       'subfid'    => $oKunenaForumMessage->catid,
                                  'sub_forum_name' => $forum[$oKunenaForumMessage->catid]->name,
                                  'title'     => $oKunenaForumMessage->subject,
                        'author'    => $this->getPushName(),
                        'authorid'  => $this->getPushAuthorId(),
                        'dateline'  => time(),
                        'author_ip' => self::getClientIp(),
                        'author_ua' => self::getClienUserAgent(),
                        'author_type' => $this->check_return_user_type(),
                        'from_app' => self::getIsFromApp(),
                        'content' => $oKunenaForumMessage->message
                    );
                if(sizeof($users))
                {
                    $pushPack['userid'] = implode(',', $users);
                }
                
                $this->push($pushPack);
		    }
		}
        return false;
    }
    /**
     * reply push(include some types push)
     *
     * @param  Array  $p
     * @return Boolean
     */
    protected function doPushReply($p) {
        $push_data = array();
        if (defined('MBQ_IN_IT') && MBQ_IN_IT) {    //mobiquo
            $topicId = $p['oMbqEtForumPost']->topicId->oriValue;
            $postId = $p['oMbqEtForumPost']->postId->oriValue;
        } else {    //native plugin
            $topicId = $p['oKunenaForumMessage']->thread;
            $postId = $p['oKunenaForumMessage']->id;
        }

         
        $db = JFactory::getDBO ();
		$query = "SELECT user_id FROM #__kunena_user_topics WHERE topic_id={$db->Quote($topicId)} AND subscribed=1";
		$db->setQuery ( $query );
		$userIds = (array) $db->loadColumn ();
		$objsKunenaUser = $this->getUsersByUserIdsExceptMe($userIds);
		$oKunenaForumTopic = $this->getTopicByTopicId($topicId);
		//send sub push
		if ($oKunenaForumTopic) {
		    $oKunenaForumMessage = $this->getPostByPostId($postId);
		    if ($oKunenaForumMessage) {
                $quoteUsers = array();
                if(preg_match_all('/\[quote="(.*?)"/si', $oKunenaForumMessage->message, $quote_matches))
                {
                    foreach($quote_matches[1] as $quote_match)
                    {
                        $quotedUserId = $this->getUserIdByName($quote_match);
                        if($quotedUserId != 0 && $quotedUserId != $this->getPushAuthorId())
                        {
                            $forum = KunenaForumCategoryHelper::getCategories($oKunenaForumMessage->catid);
                            $pushPack = array(
                                  'type'      => 'quote',
                                  'id'        => $topicId,
                                  'subid'     => $postId,
                                  'subfid'    => $oKunenaForumMessage->catid,
                                  'sub_forum_name' => $forum[$oKunenaForumMessage->catid]->name,
                                  'title'     => $oKunenaForumMessage->subject,
                                  'author'    => $this->getPushName(),
                                  'authorid'  => $this->getPushAuthorId(),
                                'dateline'  => time(),
                                'author_ip' => self::getClientIp(),
                                'author_ua' => self::getClienUserAgent(),
                                'author_type' => $this->check_return_user_type(),
                                'from_app' => self::getIsFromApp(),
                                'content' => $oKunenaForumMessage->message
                              );
                            $pushPack['userid'] = $quotedUserId;
                            $quoteUsers[] = $quotedUserId;
                            $this->push($pushPack);
                        }
                    }
                  
                }

                //can send push
                $users = array();
                foreach ($objsKunenaUser as $oKunenaUser) {
                    if(in_array($oKunenaUser->userid, $quoteUsers))
                    {
                        continue;
                    }
                    $users[] = $oKunenaUser->userid;
                }
                $forum = KunenaForumCategoryHelper::getCategories($oKunenaForumMessage->catid);
                $pushPack = array(
                      'type'      => 'sub',
                      'userid'        => '',
                      'id'        => $topicId,
                      'subid'     => $postId,
                      'subfid'    => $oKunenaForumMessage->catid,
                      'sub_forum_name' => $forum[$oKunenaForumMessage->catid]->name,
                      'title'     => $oKunenaForumMessage->subject,
                      'author'    => $this->getPushName(),
                       'authorid'  => $this->getPushAuthorId(),
                        'dateline'  => time(),
                        'author_ip' => self::getClientIp(),
                        'author_ua' => self::getClienUserAgent(),
                        'author_type' => $this->check_return_user_type(),
                        'from_app' => self::getIsFromApp(),
                        'content' => $oKunenaForumMessage->message
                  );
                if(sizeof($users))
                {
                    $pushPack['userid'] = implode(',', $users);
                }
                
                $this->push($pushPack);
		    }
		}
        return false;
    }
    /**
     * newtopic push(include some types push)
     *
     * @param  Array  $p
     * @return Boolean
     */
    protected function doPushNewMessage($p) {
        $boxId = 1;
        $oMbqEtPm = $p['oMbqEtPm'];
        $config = MbqMain::$oMbqAppEnv->pm->config;
        
        $db = JFactory::getDBO ();
        $message = $db->setQuery("SELECT a.*, b.".($config->realnames ? "name" : "username")." AS toname "
                . "FROM #__uddeim AS a "
                . "LEFT JOIN #__users AS b ON a.toid=b.id "
                . "WHERE a.fromid=".(int)$this->oJUser->id." AND a.id = " . $oMbqEtPm->msgId->oriValue . "")->loadObjectList();
        if($message){
            foreach ($message as $msg){
                if($this->oJUser->id == $msg->toid) continue;
                $pushPack = array(
                    'userid'    => $msg->toid,
                    'type'      => 'pm',
                    'id'        => $msg->id,
                    'subid'     => $boxId,
                    'title'     => $msg->message,
                    'author'    => $this->getPushName(),
                    'authorid'  => $this->getPushAuthorId(),
                    'dateline'  => time(),
                    'author_ip' => self::getClientIp(),
                    'author_ua' => self::getClienUserAgent(),
                    'author_type' => $this->check_return_user_type(),
                    'from_app' => self::getIsFromApp(),
                    'content' => $msg->message
                );
                $this->push($pushPack);
            }
        }
        return false;
    }
    
    /**
     * get users by user ids except me
     *
     * @param  Array  $userIds
     * @return  Array
     */
    protected function getUsersByUserIdsExceptMe($userIds) {
        $objsKunenaUser = array();
        foreach ($userIds as $userId) {
            $oKunenaUser = new KunenaUser($userId);
            //if ($oKunenaUser->exists() && !$oKunenaUser->isMyself() && !$oKunenaUser->isBanned()) {
            if ($oKunenaUser->exists() && !$oKunenaUser->isBanned() && ($userId != $this->oJUser->id)) {
                $objsKunenaUser[] = $oKunenaUser;
            }
        }
        return $objsKunenaUser;
    }
    
    protected function getUserIdByName($username) {
        $oKunenaUser = KunenaFactory::getUser($username);
        return $oKunenaUser->userid;
    }
    /**
     * get topic by topic id
     *
     * @param  Integer  $topicId
     * @return Mixed
     */
    protected function getTopicByTopicId($topicId) {
        $objsKunenaForumTopic = KunenaForumTopicHelper::getTopics(array($topicId));
        if ($objsKunenaForumTopic) {
            return array_shift($objsKunenaForumTopic);
        } else {
            return false;
        }
    }
    
    /**
     * get post by post id
     *
     * @param  Integer  $postId
     * @return Mixed
     */
    protected function getPostByPostId($postId) {
        $objsKunenaForumMessage = KunenaForumMessageHelper::getMessages(array($postId));
        if ($objsKunenaForumMessage) {
            return array_shift($objsKunenaForumMessage);
        } else {
            return false;
        }
    }
    
    protected function doInternalPushNewMessage($p)
    {
        $this->doPushNewMessage($p);
    }
    
   
    protected function doPushCustomMessage($push_data) {
        $this->push($push_data);
        return false;
    }
    
    public function getPushName(){
        $config = KunenaFactory::getConfig ();
        if($config->username) return $this->oJUser->username;
        else return $this->oJUser->name;
    }
    public function getPushAuthorId(){
        return $this->oJUser->id;
    }
    public function check_return_user_type()
    {
        $kuser = KunenaUserHelper::getMyself ();
        if($kuser->isAdmin())
        {
            return "admin";
        }
        else if($kuser->moderator == 1)
        {
            return "moderator";
        }
        return "normal";
    }
    protected function doInternalPushThank($p)
    {
        $this->doPushThank($p);
    }
    protected function doInternalPushNewTopic($p)
    {
        $this->doPushNewtopic($p);
    }
    
    protected function doInternalPushReply($p)
    {
        $this->doPushReply($p);
    }
    protected function doInternalPushReplyConversation($p){}


    protected function doInternalPushNewConversation($p){}

    protected function doInternalPushLike($p){}

    protected function doInternalPushNewSubscription($p){}

    protected function doInternalPushDeleteTopic($p){}

    protected function doInternalPushDeletePost($p){}
}

