<?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_Cron extends XenForo_Model
{
    public static function updateImpressionCounts()
    {
        $self = XenForo_Model::create(__CLASS__);
        $self->_updateImpressionsCount();
    }

    public static function sendExpiringNotifications()
    {
        $self = XenForo_Model::create(__CLASS__);
        $self->_sendExpiringNotifications();
    }

    public static function sendBannersStatisticsNotifications()
    {
        $self = XenForo_Model::create(__CLASS__);
        $self->_sendBannersStatisticsNotifications();
    }

    public static function updateBannerStatus($bannerId = false)
    {
        if (is_array($bannerId) AND isset($bannerId['addon_id'])) {
            $bannerId = false;
        }

        $self = XenForo_Model::create(__CLASS__);
        $self->_updateBannerStatus($bannerId);
    }

    public static function generateStatsSummary()
    {
        $self = XenForo_Model::create(__CLASS__);

        $self->_removeExpiredBanners();
        $self->_updateStatsSummary();
    }

    protected function _sendBannersStatisticsNotifications()
    {
        $options = Xenforo_Application::get('options');
        if ($options->xcas_ad_send_banner_statistic) {

            $users = $this->_getDb()->fetchAll("
                 SELECT user_id FROM xcas_banner
                 WHERE status = 'active'
            ");

            $usersListBannerOwner = '';
            foreach ($users as $usersId) {
                $usersListBannerOwner = $usersListBannerOwner . $usersId['user_id'] . ",";
            }

            $userIdList = array_unique(array_diff(explode(",", $usersListBannerOwner), array('')));

            if (!empty($userIdList)) {
                $userNameArray = $this->_getDb()->fetchPairs('
                    SELECT user_id, username
                    FROM xf_user
                    WHERE user_id IN (' . implode(',', $userIdList) . ')
                ');
                $userIdList = array_keys($userNameArray);
                $userEmailArray = $this->_getDb()->fetchPairs('
                    SELECT user_id, email
                    FROM xf_user
                    WHERE user_id IN (' . implode(',', $userIdList) . ')
                ');

            } else {
                $userNameArray = array();
                $userEmailArray = array();
            }

            foreach ($userIdList as $userId) {
                $banners = $this->_getBannerModel()->getUserBanners($userId);

                if (empty($banners)) {
                    continue;
                }

                $username = '';

                if (!empty($userNameArray[$userId])) {
                    $username = $userNameArray[$userId];
                }

                $conditions = array(
                        'start_date' => time() - 7 * 86400,
                        'end_date' => time()
                );

                $notificationArray = $this->_getStatsModel()->getBannerStatisticsForExport($banners, $conditions);
                $email = $userEmailArray[$userId];
                $mail = XenForo_Mail::create('xcas_ad_banner_statistic', array(
                        'notifications' => $notificationArray,
                        'username' => $username
                ));
                $mail->send($email);
            }
        }

    }

    protected function _sendExpiringNotifications()
    {
        $banners = $this->_getDb()->fetchAll("
            SELECT * FROM xcas_banner
        ");

        /** @var XenCentral_AdServer_Model_Notification $notificationModel */
        $notificationModel = $this->getModelFromCache('XenCentral_AdServer_Model_Notification');

        foreach ($banners AS $banner) {
            if ($notificationKey = $notificationModel->getBannerNotificationKey($banner)) {
                $this->_getDb()->update(
                        'xcas_banner',
                        array(
                                'notifications_sent' => $banner['notifications_sent']
                        ),
                        array('bannerId' => $banner['bannerId'])
                );
                foreach (explode('|', $notificationKey) AS $notificationType) {
                    if (!$notificationType) {
                        continue;
                    }

                    if ($notificationModel->isUserNotification($notificationType)) {
                        foreach (explode(',', $banner['user_id']) AS $user_id) {
                            $user = $this->_getUserModel()->getUserById($user_id);

                            if (!$user) {
                                continue;
                            }

                            $params = array(
                                    'user' => $user,
                                    'banner' => $banner
                            );

                            $notificationModel->sendUserNotification($notificationType, $user, $params);
                        }
                    } else if ($notificationModel->isAdminNotification($notificationType)) {
                        $params = array(
                                'banner' => $banner
                        );
                        $notificationModel->sendAdminNotification($notificationType, $params);
                    } else {
                        throw new XenForo_Exception('Unknown notification type - ' . $notificationType);
                    }
                }
            }
        }
    }

    protected function _updateImpressionsCount()
    {
        $this->_getStatsModel()->buildImpressionCounts();
    }

    protected function _removeExpiredBanners()
    {
        $days = XenForo_Application::getOptions()->get('xcas_autoremove_expired_campaigns');
        if (!$days) {
            return;
        }

        $db = $this->_getDb();

        $banners = $db->fetchAll('
            SELECT * FROM xcas_banner
            WHERE user_id!=\'\'
            AND active_from!=0
            AND active_from<?
            AND status=?
        ', array(
                time() - $days * 86400,
                'inactive'
        ));

        foreach($banners AS $banner) {
            $dw=XenForo_DataWriter::create('XenCentral_AdServer_DataWriter_Banner');
            $dw->setExistingData($banner, true);
            $dw->delete();
        }
    }

    protected function _updateStatsSummary()
    {
        $zones = $this->_getZoneModel()->getAllZones();

        foreach ($zones AS $zone) {
            $stats = array(
                            'content_type' => 'zone',
                            'content_id' => $zone['zoneId'],
                    ) + $this->_getStatsModel()->getZoneAverageStats($zone['zoneId']);
            $this->_getDb()->query("
                REPLACE INTO xcas_stats_summary (content_type, content_id, impressions, clicks, running_time)
                VALUES (?, ?, ?, ?, ?)
            ", $stats);
        }

        $banners = $this->_getBannerModel()->getActiveBanners();

        foreach ($banners AS $banner) {
            $stats = array(
                            'content_type' => 'banner',
                            'content_id' => $banner['bannerId'],
                    ) + $this->_getStatsModel()->getBannerAverageStats($banner['bannerId']);
            $this->_getDb()->query("
                REPLACE INTO xcas_stats_summary (content_type, content_id, impressions, clicks, running_time)
                VALUES (?, ?, ?, ?, ?)
            ", $stats);
        }

        // update caches
        $this->_getZoneModel()->updateCache();
        $this->_getBannerModel()->updateCache();
    }

    protected function _updateBannerStatus($bannerId = false)
    {
        // run a query for bulk update of banner statuses
        if ($bannerId) {
            $condition = 'WHERE banner.bannerId=' . $bannerId;
        } else {
            $condition = '';
        }

        $ads = $this->_getDb()->fetchAll("
            SELECT banner.*, zone.owners
            FROM xcas_banner AS banner
            LEFT JOIN xcas_zone AS zone ON zone.zoneId=banner.zoneId
            $condition
        ");

        $statusChanged = false;

        foreach ($ads AS $ad) {
            $newStatus = false;
            if ($ad['owners']) {
                // get the owners, and make sure they have enough credit for the ad to be displayed
                $owner = $this->_getUserModel()->getActiveCampaignOwner($ad['owners']);
                if (!$owner) {
                    if ($ad['status'] == 'active') {
                        $newStatus = 'paused';
                    }
                } else {
                    if ($ad['status'] == 'paused') {
                        $newStatus = 'active';
                    }
                }
            } else if (
                    (
                            $ad['active_from']
                            OR $ad['active_to']
                    )
                    AND
                    $ad['active_from'] < time()
                    AND
                    (
                            $ad['active_to'] > time()
                            OR $ad['active_to'] == 0
                    )
                    OR
                    (
                            $ad['impressions_left'] > 0
                            OR $ad['impressions_left'] == -1
                    )
            ) {
                if ($ad['status'] != 'moderated') {
                    $newStatus = 'active';
                }
            } else {
                if ($ad['status'] == 'active') {
                    // deactivate
                    $newStatus = 'inactive';
                }
            }

            if ($newStatus AND $newStatus != $ad['status']) {
                $statusChanged = true;
                $this->_getDb()->update('xcas_banner', array('status' => $newStatus), 'bannerId=' . $ad['bannerId']);
            }
        }

        // rebuild caches
        if ($statusChanged) {
            $this->_getBannerModel()->updateCache();
        }
    }

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

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

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

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