<?php
/**
* @package XenCentral Ad Server
* @author Skydevelop EU
* @copyright Drnoyan & Nalyan LDA, Portugal, EU
* @license http://www.dnf.pt/eula.html
* @link http://www.skydevelop.com
* @revision 97
* @version 2.0.0 beta 3 rev. 3
*/


class XenCentral_AdServer_Model_Notification extends XenCentral_AdServer_Model_Abstract
{
    const NOTIFICATION_DAY = 1;
    const NOTIFICATION_WEEK = 2;
    const NOTIFICATION_IMPRESSION = 4;
    const NOTIFICATION_EXPIRED = 8;

    const TYPE_ADMIN_UPLOADED = 'admin_uploaded';
    const TYPE_ADMIN_ACTIVATED = 'admin_activated';
    const TYPE_ADMIN_EXPIRED = 'admin_expired';

    const TYPE_USER_APPROVED = 'user_approved';
    const TYPE_USER_EXPIRED = 'user_expired';
    const TYPE_USER_EXPIRE_SOON = 'user_expire_soon';

    public function isAdminNotification($type)
    {
        return in_array($type, array(
                self::TYPE_ADMIN_ACTIVATED,
                self::TYPE_ADMIN_EXPIRED,
                self::TYPE_ADMIN_UPLOADED,
        ));
    }

    public function isUserNotification($type)
    {
        return in_array($type, array(
                self::TYPE_USER_EXPIRED,
                self::TYPE_USER_APPROVED,
                self::TYPE_USER_EXPIRE_SOON,
        ));
    }

    /*public function sendAdminUploadedNotification($params)
    {
        return $this->sendAdminNotification(self::TYPE_ADMIN_UPLOADED, $params);
    }

    public function sendAdminActivatedNotification($params)
    {
        return $this->sendAdminNotification(self::TYPE_ADMIN_ACTIVATED, $params);
    }
    */

    public function sendAdminNotification($notificationKey, $params)
    {
        $emailOption = $this->_getOptionsModel()->notify_admin_email();
        if (!empty($emailOption[$notificationKey])) {
            $adminUsers = $this->_getAllAdminUsers();

            foreach ($adminUsers AS $admin) {
                $this->_sendEmailNotification($notificationKey, $admin, $params);
            }
        }

        $alertOption = $this->_getOptionsModel()->notify_admin_alert();

        if (!empty($alertOption[$notificationKey])) {
            $adminUsers = $this->_getAllAdminUsers();

            foreach ($adminUsers AS $admin) {
                $this->_sendAlertNotification($notificationKey, $admin, $params);
            }
        }
    }

    public function sendUserNotification($notificationKey, $user, $params)
    {
        $emailOption = $this->_getOptionsModel()->notify_user_email();
        if (!empty($emailOption[$notificationKey])) {
            $this->_sendEmailNotification($notificationKey, $user, $params);
        }

        $alertOption = $this->_getOptionsModel()->notify_user_alert();
        if (!empty($alertOption[$notificationKey])) {
            $this->_sendAlertNotification($notificationKey, $user, $params);
        }
    }

    protected function _sendEmailNotification($notificationKey, $user, $params)
    {
        $args = $this->_getArgsFromParams($user, $params);

        if(!empty($params['banner']['expire_phrase'])) {
            $args['expire_phrase']=new XenForo_Phrase('xcas_expire_phrase_'. $params['banner']['expire_phrase'], $params['banner']);
        }

        $params['subject']=(new XenForo_Phrase(
                'xcas_email_'.$notificationKey.'_subject',
                $args
        )).'';
        $params['plain']= (new XenForo_Phrase(
                'xcas_email_' . $notificationKey . '_plain',
                $args
        )).'';
        $params['html']= (new XenForo_Phrase(
                'xcas_email_' . $notificationKey . '_html',
                $args
        )).'';

        $mail = XenForo_Mail::create('xcas_notification_email', $params, $user['language_id']);

        return $mail->send($user['email']);
    }

    protected function _sendAlertNotification($notificationKey, $user, $params)
    {
        $args = $this->_getArgsFromParams($user, $params);

        if (!empty($params['banner']['expire_phrase'])) {
            $args['expire_phrase'] = new XenForo_Phrase('xcas_expire_phrase_' . $params['banner']['expire_phrase'], $params['banner']);
        }

        $sender_user=$this->_getAlertSenderUser();

        if(!$sender_user) {
            return false;
        }

        XenForo_Model_Alert::alert(
                $user['user_id'],
                $sender_user['user_id'],
                $sender_user['username'],
                'banner',
                $params['banner']['bannerId'],
                $notificationKey,
                $args
        );

        return true;
    }

    /**
     * @param $banner
     * @return string|bool day|week|impression
     *
     * Returns false if no notification should be sent, and notification key (day, week, impression etc.) otherwise
     */
    public function getBannerNotificationKey(&$banner)
    {
        if (!$banner['user_id']) {
            // not a user-banner
            return false;
        }

        if ($banner['status'] == 'inactive') {
            // check if expired notice was sent before
            if (($banner['notifications_sent'] & self::NOTIFICATION_EXPIRED) == 0) {
                $banner['notifications_sent'] += self::NOTIFICATION_EXPIRED;
                return self::TYPE_ADMIN_EXPIRED . '|' . self::TYPE_USER_EXPIRED;
            }
            return false;
        } else if($banner['status']!='active') {
            return false;
        }

        if ($banner['active_to'] AND $banner['active_to'] > time()) {
            $timeDiff = $banner['active_to'] - time();

            if ($timeDiff < 86400) {
                if (($banner['notifications_sent'] & self::NOTIFICATION_DAY) == 0) {
                    $banner['notifications_sent'] += self::NOTIFICATION_DAY;
                    $banner['expire_phrase'] = '1_day';
                    return self::TYPE_USER_EXPIRE_SOON;
                }
            } else if (
                    $timeDiff < 7 * 86400
                    AND $banner['active_from']
                    AND $banner['active_to'] - $banner['active_from'] >= 14 * 86400
            ) {
                // send weekly expiration email only for banners with length of activation more than 14 days
                if (($banner['notifications_sent'] & self::NOTIFICATION_WEEK) == 0) {
                    $banner['notifications_sent'] += self::NOTIFICATION_WEEK;
                    $banner['expire_phrase'] = '7_day';
                    return self::TYPE_USER_EXPIRE_SOON;
                }
            }
        }

        if (
                $banner['active_to']<time()
                AND
                $banner['impressions_left'] > 0 AND $banner['impressions_left'] < $this->_getOptionsModel()->getImpressionNotificationThreashold()
        ) {
            if (($banner['notifications_sent'] & self::NOTIFICATION_IMPRESSION) == 0) {
                $banner['notifications_sent'] += self::NOTIFICATION_IMPRESSION;
                $banner['expire_phrase'] = 'impression';
                return self::TYPE_USER_EXPIRE_SOON;
            }
        }

        return false;
    }

    /**
     * @param $banner array
     * @param $notificationKey string day|week|impression
     */
    public function sendBannerNotification($banner, $notificationKey)
    {
        foreach (explode(',', $banner['user_id']) AS $user_id) {
            $user = $this->_getUserModel()->getUserById($user_id);

            if (!$user) {
                continue;
            }

            $email_template = 'xcas_expire_notification_' . $notificationKey;
            $params = array(
                    'user' => $user,
                    'banner' => $banner
            );
        }
    }

    protected function _getAlertSenderUser()
    {
        static $user;

        if(is_null($user)) {
            $userId=$this->_getOptionsModel()->alert_sender_id();
            if(!$userId) {
                return false;
            }

            $user=$this->_getUserModel()->getUserById($userId);
        }

        return $user;
    }

    /**
     * @param $email_template
     * @param $user
     * @param $params
     * @param bool $sender_id
     * @return bool
     * @throws Exception
     * @throws XenForo_Exception
     * Sends the notification to $user based on $email_template with $params provided as params
     */
    public function sendRawNotification($email_template, $user, $params, $sender_id = false)
    {
        $mail = XenForo_Mail::create('xcas_ad_approved_message', $params, $user['language_id']);

        $contents = $mail->prepareMailContents();

        $message = $contents['bodyText'];

        if ($sender_id == false) {
            $from = XenForo_Visitor::getInstance()->toArray();
        } else {
            $from = $this->_getUserModel()->getUserById($sender_id);
        }

        if (!$from OR !$from['user_id']) {
            return false;
        }

        /** @var XenForo_DataWriter_ConversationMaster $conversationDw */
        $conversationDw = XenForo_DataWriter::create('XenForo_DataWriter_ConversationMaster');
        $conversationDw->setExtraData(XenForo_DataWriter_ConversationMaster::DATA_ACTION_USER, $from);
        $conversationDw->set('user_id', $from['user_id']);
        $conversationDw->set('username', $from['username']);
        $conversationDw->set('title', $contents['subject']);
        $conversationDw->set('open_invite', 0);
        $conversationDw->set('conversation_open', 0);
        $conversationDw->addRecipientUserNames(array($user['username']));

        $messageDw = $conversationDw->getFirstMessageDw();
        $messageDw->set('message', $message);

        $conversationDw->preSave();

        $conversationDw->save();

        $conversation = $conversationDw->getMergedData();

        $this->_getConversationModel()->markConversationAsRead(
                $conversation['conversation_id'], $from['user_id'], XenForo_Application::$time
        );

        return true;
    }

    protected function _getAllAdminUsers()
    {
        static $users;

        if (is_array($users)) {
            return $users;
        }

        /** @var XenForo_Model_Admin $adminModel */
        $adminModel = XenForo_Model::create('XenForo_Model_Admin');

        $users = $this->_getUserModel()->getUsers(array('is_admin' => 1), array('join' => XenForo_Model_User::FETCH_USER_PERMISSIONS));

        foreach ($users AS $userId => $user) {
            if (!$this->_getUserModel()->isUserSuperAdmin($user)) {
                $adminPermissions = $adminModel->getAdminPermissionCacheForUser(
                        $user['user_id']
                );

                if (empty($adminPermissions['xcas_manage_ads'])) {
                    unset($users[$userId]);
                }
            }
        }

        return $users;
    }

    /**
     * @return XenForo_Model_User
     */
    protected function _getUserModel()
    {
        return $this->getModelFromCache('XenForo_Model_User');
    }

    /**
     * @return XenForo_Model_Conversation
     */
    protected function _getConversationModel()
    {
        return $this->getModelFromCache('XenForo_Model_Conversation');
    }

    /**
     * @param $user
     * @param $params
     * @return array
     */
    protected function _getArgsFromParams($user, $params)
    {
        $args = array();

        $args['current_user_name'] = $user['username'];

        $args['banner_title'] = $params['banner']['title'];
        $args['bannerId'] = $params['banner']['bannerId'];
        $args['edit_banner_link'] = XenForo_Link::buildAdminLink('full:xcas/banner/edit', $params['banner']);
        $args['view_banners_link'] = XenForo_Link::buildPublicLink('full:ads', $params['banner']);

        if (!empty($params['user'])) {
            $args['user_id'] = $params['user']['user_id'];
            $args['username'] = $params['user']['username'];
            $args['user_link'] = XenForo_Link::buildPublicLink('full:members', $params['user']);
        }

        $args['boardTitle'] = XenForo_Application::getOptions()->get('boardTitle');
        return $args;
    }


}