<?php
/********************************************************************************
 * (c)1337 aheadware.com - All rights reserved
 ********************************************************************************/

require_once __DIR__ . '/../../config/boot_global.php';
require_once __DIR__ . '/../../config/boot_local.php';

// Dependency - only used by this script
include_once( dirname(__FILE__) . '/../../../../../../dependencies/mysqldump-php-master/src/Ifsnop/Mysqldump/Mysqldump.php');

class TB_Server_Cron_DailyWorker extends TB_Server_Core_CronBase {

    /**
     * Delete outdated
     * @throws Exception
     */
    protected function run()
    {
        //
        // Process premium packages
        //
        $this->processPremium();

        //
        // Send logs
        //
        $this->sendLogs();

        //
        // Generate and send stats
        //
        $this->sendStats();

        //
        // Send daily reminder to new teams
        //
        $this->sendMailReminder( 2 );
        $this->sendMailReminder( 4 );
        $this->sendMailReminder( 8 );
    }

    /**
     * Processes outdated premium logs
     */
    protected function processPremium()
    {
        $db = TB_Shared_Db_TeamData::get();
        $entPremiumLogs = TB_Shared_Ent_TeamData_PremiumLog::getAllOutdated();

        /** @var TB_Shared_Ent_TeamData_PremiumLog $entOutdatedPremiumLog */
        foreach( $entPremiumLogs as $entOutdatedPremiumLog )
        {
            /** @var TB_Shared_Ent_TeamData_Team $team */
            $team = TB_Shared_Ent_TeamData_Team::get( $entOutdatedPremiumLog->team_id );

            if ( is_null( $team ) )
            {
                // No teams means, that the team has been dissolved by now.
                // That's why we mark this premium log as PROCESSED (eq. CLOSED)
                $entOutdatedPremiumLog->status = TB_Shared_Ent_TeamData_PremiumLog::STATUS_CLOSED;
                $entOutdatedPremiumLog->comment = 'Team has been dissolved.';
                $entOutdatedPremiumLog->save();
                continue;
            }

            /** @var TB_Shared_Ent_TeamData_PremiumLog $entNextPremiumLog */
            $entNextPremiumLog = TB_Shared_Ent_TeamData_PremiumLog::getCurrentPremiumLogForTeam( $team );
            // If team has an upcoming premium log
            if ( $entNextPremiumLog instanceof TB_Shared_Ent_TeamData_PremiumLog )
            {
                $db->beginTransaction();
                try
                {
                    $entOutdatedPremiumLog->status = TB_Shared_Ent_TeamData_PremiumLog::STATUS_CLOSED;
                    $entOutdatedPremiumLog->save();

                    $team->active_premium_package = $entNextPremiumLog->package_id;
                    $team->save();

                    $entNextPremiumLog->status = TB_Shared_Ent_TeamData_PremiumLog::STATUS_ACTIVE;
                    $entNextPremiumLog->save();

                    $db->commit();
                }
                catch ( Exception $e )
                {
                    $db->rollBack();
                    TB_Server_Utils_Log::get()->log( $e );
                    TB_Server_Utils_Log::get()->log( 'PREMIUM: Cannot activate next premium log for team: ' . $team->id );
                }
            }
            else
            {
                // No more premium packages - back to standard
                $db->beginTransaction();
                try
                {
                    $entOutdatedPremiumLog->status = TB_Shared_Ent_TeamData_PremiumLog::STATUS_CLOSED;
                    $entOutdatedPremiumLog->save();

                    $team->active_premium_package = TB_Server_Core_Premium::PREMIUM_PACKAGE_STANDARD;
                    $team->save();

                    $db->commit();

                    try
                    {
                        TB_Server_Core_Premium::notifyTeamAboutPremiumLoss( $team );
                    }
                    catch ( Exception $e )
                    {
                        TB_Server_Utils_Log::get()->log( $e );
                    }
                }
                catch ( Exception $e )
                {
                    $db->rollBack();
                    TB_Server_Utils_Log::get()->log( $e );
                    TB_Server_Utils_Log::get()->log( 'PREMIUM: Cannot reset to STANDARD for team: ' . $team->id );
                }
            }


        }
    }


    /**
     * @param int $numDays
     */
    protected function sendMailReminder( $numDays )
    {
        $dbh = TB_Shared_Db_TeamData::get();
        $sql = "CALL proc_getRecentlyStartedTeams($numDays)";
        $stmt = $dbh->query( $sql );
        $rows = $stmt->fetchAll( PDO::FETCH_ASSOC );
        $stmt->closeCursor();
        $stmt = null;
        TB_Shared_Db_TeamData::close();

        foreach( $rows as $row )
        {
            // Collect required data
            $accountId = isset( $row[ 'account_id' ] ) ? $row[ 'account_id' ] : NULL;
            $firstName = isset( $row[ 'first_name' ] ) ? $row[ 'first_name' ] : NULL;
            $lastName =  isset( $row[ 'last_name' ] ) ? $row[ 'last_name' ] : NULL;
            $teamName =  isset( $row[ 'display_name' ] ) ? $row[ 'display_name' ] : NULL;
            $numBuddies = isset( $row[ 'Teilnehmer' ] ) ? $row[ 'Teilnehmer' ] : NULL;
            $numAppointments = isset( $row[ 'Termine' ] ) ? $row[ 'Termine' ] : NULL;
            $numReactions = isset( $row[ 'ZuAbsagen' ] ) ? $row[ 'ZuAbsagen' ] : NULL;

            /** @var TB_Shared_Ent_Core_Account $entAccount */
            $entAccount = TB_Shared_Ent_Core_Account::get( $accountId );
            if ( !(  $entAccount instanceof  TB_Shared_Ent_Core_Account ) || $entAccount->subscribed_news === 0 )
            {
                continue;
            }

            $data = array(
                'firstName' => $firstName,
                'lastName' => $lastName,
                'teamName' => $teamName,
                'numBuddies' => $numBuddies,
                'numAppointments' => $numAppointments,
                'numReactions' => $numReactions
            );

            switch( $numDays )
            {
                case 2:
                    TB_Server_Utils_Mail::sendReminder2( $entAccount, $data );
                break;

                case 4:
                    TB_Server_Utils_Mail::sendReminder4( $entAccount, $data );
                break;

                case 8:
                    TB_Server_Utils_Mail::sendReminder8( $entAccount, $data );
                break;
            }

        }
    }



    /**
     * Generate some stats and send them via email
     */
    protected function sendStats() {

        // Time for active
        $yesterdayStart = date( 'Y-m-d', time() - 60 * 60 * 24 ) . ' 00:00:00';
        $yesterdayEnd = date( 'Y-m-d', time() - 60 * 60 * 24 ) . ' 23:59:59';
        $yesterdayStartTS = strtotime( $yesterdayStart );
        $yesterdayEndTS = strtotime( $yesterdayEnd );

        // Overall
        $totalAccounts = 0;
        $totalTeams = 0;

        // Premiums
        $totalPremiumTeams = 0;
        $totalPremium25 = 0;
        $totalPremium50 = 0;
        $totalPremium100 = 0;
        $totalPremiumGross = 0; // Monthly


        // Active
        $activeAccounts = 0;
        $activeTeams = 0;

        // Mobile
        $numAndroid = 0;
        $numIOS = 0;

        // Total accounts
        $dbhAcc = TB_Shared_Ent_Core_Account::getDbh();
        $sql  = "SELECT COUNT(*) as total_amount FROM " . TB_Shared_Ent_Core_Account::getTable();
        $stmt = $dbhAcc->prepare( $sql );
        $stmt->execute();
        $row = $stmt->fetch( PDO::FETCH_ASSOC );
        if ( is_array( $row ) && isset( $row[ 'total_amount' ] ) ) {
            $totalAccounts = (int)$row[ 'total_amount' ];
        }

        // Mobile installation (Android+iOS)
        $dbhDevRec = TB_Shared_Ent_Core_DeviceReg::getDbh();
        $sql = "SELECT COUNT(*) as num_android FROM " . TB_Shared_Ent_Core_DeviceReg::getTable() . " ";
        $sql .= "WHERE platform = '" . TB_Shared_Ent_Core_DeviceReg::PLATFORM_ANDROID . "'";
        $stmt = $dbhDevRec->prepare( $sql );
        $stmt->execute();
        $row = $stmt->fetch( PDO::FETCH_ASSOC );
        if ( is_array( $row ) && isset( $row[ 'num_android' ] ) ) {
            $numAndroid = (int)$row[ 'num_android' ];
        }
        $sql = "SELECT COUNT(*) as num_ios FROM " . TB_Shared_Ent_Core_DeviceReg::getTable() . " ";
        $sql .= "WHERE platform = '" . TB_Shared_Ent_Core_DeviceReg::PLATFORM_IOS . "'";
        $stmt = $dbhDevRec->prepare( $sql );
        $stmt->execute();
        $row = $stmt->fetch( PDO::FETCH_ASSOC );
        if ( is_array( $row ) && isset( $row[ 'num_ios' ] ) ) {
            $numIOS = (int)$row[ 'num_ios' ];
        }

        // Total teams
        $dbhTeam = TB_Shared_Ent_TeamData_Team::getDbh();
        $sql  = "SELECT COUNT(*) as total_amount FROM " . TB_Shared_Ent_TeamData_Team::getTable();
        $stmt = $dbhTeam->prepare( $sql );
        $stmt->execute();
        $row = $stmt->fetch( PDO::FETCH_ASSOC );
        if ( is_array( $row ) && isset( $row[ 'total_amount' ] ) ) {
            $totalTeams = (int)$row[ 'total_amount' ];
        }

        // Active accounts
        $sql = "SELECT COUNT(*) AS actives FROM `profile_timestamp` WHERE from_unixtime(last_online) > date_sub(curdate(), interval 5 day)";
        $stmt = $dbhTeam->prepare( $sql );
        $stmt->execute();
        $row = $stmt->fetch( PDO::FETCH_ASSOC );
        if ( is_array( $row ) && isset( $row[ 'actives' ] ) ) {
            $activeAccounts = (int)$row[ 'actives' ];
        }

        // Active Teams
        $dbhTD = TB_Shared_Db_TeamData::get();
        $sql = "SELECT COUNT( distinct(c.display_name) ) AS active_teams
FROM  `profile_timestamp` a
INNER JOIN  `profile` b ON a.profile_id = b.account_id
INNER JOIN  `team` c ON b.team_id = c.id
WHERE from_unixtime(a.last_online) > date_sub(curdate(), interval 5 day)
and c.id in (select ID
from
(SELECT a.id as ID, count(c.account_id) as counter
FROM  `team` a
INNER JOIN  `profile` c ON a.id = c.team_id
group by a.id) as te
where counter > 5)";
        $stmt = $dbhTD->prepare( $sql );
        $stmt->execute();
        $row = $stmt->fetch( PDO::FETCH_ASSOC );
        if ( is_array( $row ) && isset( $row[ 'active_teams' ] ) ) {
            $activeTeams = (int)$row[ 'active_teams' ];
        }

        // Get account ids and email from newly created accounts
        $newTrainers = array();
        $sql  = "SELECT id, email, is_validated FROM " . TB_Shared_Ent_Core_Account::getTable() . " ";
        $sql .= "WHERE created_dt > :yesterdayStart AND created_dt < :yesterdayEnd";
        $stmt = $dbhAcc->prepare( $sql );
        $stmt->execute(array( ':yesterdayStart' => $yesterdayStart, ':yesterdayEnd' => $yesterdayEnd ) );
        $rows = $stmt->fetchAll( PDO::FETCH_ASSOC );
        if ( is_array( $rows ) && 0 < count( $rows ) ) {
            $dbhTD = TB_Shared_Db_TeamData::get();
            foreach( $rows as $row ) {
                $sql  = "SELECT * FROM " . TB_Shared_Ent_TeamData_Profile::getTable() . " as p, ";
                $sql .= TB_Shared_Ent_TeamData_Team::getTable() . " as t WHERE p.account_id = :accountId  AND ";
                $sql .= "p.role='trainer' AND p.team_id=t.id LIMIT 1";
                $stmt = $dbhTD->prepare( $sql );
                $stmt->execute( array( ':accountId' => $row[ 'id' ] ) );
                $entry = $stmt->fetch( PDO::FETCH_ASSOC );
                if ( is_array( $entry ) ) {
                    $entry[ 'email' ] = $row[ 'email' ];
                    $entry[ 'is_validated' ] = $row[ 'is_validated' ];
                    array_push( $newTrainers, $entry );
                }
            }
        }

        // Premium
        // Total
        $dbhTeam = TB_Shared_Ent_TeamData_Team::getDbh();
        $sql  = "SELECT COUNT(*) as total_amount FROM " . TB_Shared_Ent_TeamData_PremiumLog::getTable() . " ";
        $sql .= "WHERE package_id <> '" . TB_Server_Core_Premium::PREMIUM_PACKAGE_PREMIUM100_FREE . "' AND ";
        $sql .= "`status` = '" . TB_Shared_Ent_TeamData_PremiumLog::STATUS_ACTIVE . "' AND ";
        $sql .= "valid_from_dt < NOW() AND ";
        $sql .= "( valid_until_dt > NOW() OR valid_until_dt IS NULL )";
        $stmt = $dbhTeam->prepare( $sql );
        $stmt->execute();
        $row = $stmt->fetch( PDO::FETCH_ASSOC );
        if ( is_array( $row ) && isset( $row[ 'total_amount' ] ) ) {
            $totalPremiumTeams = (int)$row[ 'total_amount' ];
        }

        $sql  = "SELECT COUNT(*) as total_amount FROM " . TB_Shared_Ent_TeamData_PremiumLog::getTable() . " ";
        $sql .= "WHERE package_id = '" . TB_Server_Core_Premium::PREMIUM_PACKAGE_PREMIUM25 . "' AND ";
        $sql .= "`status` = '" . TB_Shared_Ent_TeamData_PremiumLog::STATUS_ACTIVE . "' AND ";
        $sql .= "valid_from_dt < NOW() AND ";
        $sql .= "( valid_until_dt > NOW() OR valid_until_dt IS NULL )";
        $stmt = $dbhTeam->prepare( $sql );
        $stmt->execute();
        $row = $stmt->fetch( PDO::FETCH_ASSOC );
        if ( is_array( $row ) && isset( $row[ 'total_amount' ] ) ) {
            $totalPremium25 = (int)$row[ 'total_amount' ];
        }

        $sql  = "SELECT COUNT(*) as total_amount FROM " . TB_Shared_Ent_TeamData_PremiumLog::getTable() . " ";
        $sql .= "WHERE package_id = '" . TB_Server_Core_Premium::PREMIUM_PACKAGE_PREMIUM50 . "' AND ";
        $sql .= "`status` = '" . TB_Shared_Ent_TeamData_PremiumLog::STATUS_ACTIVE . "' AND ";
        $sql .= "valid_from_dt < NOW() AND ";
        $sql .= "( valid_until_dt > NOW() OR valid_until_dt IS NULL )";
        $stmt = $dbhTeam->prepare( $sql );
        $stmt->execute();
        $row = $stmt->fetch( PDO::FETCH_ASSOC );
        if ( is_array( $row ) && isset( $row[ 'total_amount' ] ) ) {
            $totalPremium50 = (int)$row[ 'total_amount' ];
        }

        $sql  = "SELECT COUNT(*) as total_amount FROM " . TB_Shared_Ent_TeamData_PremiumLog::getTable() . " ";
        $sql .= "WHERE package_id = '" . TB_Server_Core_Premium::PREMIUM_PACKAGE_PREMIUM100 . "' AND ";
        $sql .= "`status` = '" . TB_Shared_Ent_TeamData_PremiumLog::STATUS_ACTIVE . "' AND ";
        $sql .= "valid_from_dt < NOW() AND ";
        $sql .= "( valid_until_dt > NOW() OR valid_until_dt IS NULL )";
        $stmt = $dbhTeam->prepare( $sql );
        $stmt->execute();
        $row = $stmt->fetch( PDO::FETCH_ASSOC );
        if ( is_array( $row ) && isset( $row[ 'total_amount' ] ) ) {
            $totalPremium100 = (int)$row[ 'total_amount' ];
        }

        $totalPremiumGross  = $totalPremium25 * TB_Server_Core_Premium::getPackagePrice( TB_Server_Core_Premium::PREMIUM_PACKAGE_PREMIUM25 );
        $totalPremiumGross += $totalPremium50 * TB_Server_Core_Premium::getPackagePrice( TB_Server_Core_Premium::PREMIUM_PACKAGE_PREMIUM50 );
        $totalPremiumGross += $totalPremium100 * TB_Server_Core_Premium::getPackagePrice( TB_Server_Core_Premium::PREMIUM_PACKAGE_PREMIUM100 );

        $stats  = "<pre>";
        $stats .= "TBuddy Statistik - " . date( 'd.m.Y' ) . "\n\r" . "\n\r";
        $stats .= "Accounts insgesamt: " . $totalAccounts . "\n\r";
        $stats .= "Mobile Installationen insgesamt (iOS/Android): " . ($numIOS+$numAndroid) . " (" . $numIOS . "/" . $numAndroid .")" . "\n\r";
        $stats .= "Teams insgesamt: " . $totalTeams . "\n\r";
        $stats .= "Teams aktiv: " . $activeTeams . "\n\r";
        $stats .= "Accounts aktiv: " . $activeAccounts . "\n\r";
        $stats .= "\n\r" . "\n\r";
        $stats .= "Premium: " . "\n\r" . "\n\r";
        $stats .= "Total: " . $totalPremiumTeams . "\n\r";
        $stats .= "Premium25: " . $totalPremium25 . "\n\r";
        $stats .= "Premium50: " . $totalPremium50 . "\n\r";
        $stats .= "Premium100: " . $totalPremium100 . "\n\r";
        $stats .= "Monatliches Brutto: " . $totalPremiumGross . "€" . "\n\r";
        $stats .= "Neue Teams: " . "\n\r" . "\n\r";
        if ( 0 < count( $newTrainers ) ) {
            foreach( $newTrainers as $newTrainer ) {
                $stats .= "Teamname: " . $newTrainer[ 'display_name' ] . "\n\r";
                $stats .= "Teamkategorie: " . ( isset( $newTrainer[ 'category' ] ) ?  $newTrainer[ 'category' ] : '---' ) . "\n\r";
                $stats .= "Trainer Name: " . $newTrainer[ 'first_name' ] . " " . $newTrainer[ 'last_name' ] .  "\n\r";
                $stats .= "Email Adresse: " . $newTrainer[ 'email' ] . "\n\r";
                $stats .= "Validiert: ";
                $stats .= ( 1 == $newTrainer[ 'is_validated'] ) ? "Ja" : "Nein" . "\n\r";
                $stats .= "\n\r" . "\n\r";
            }
        } else {
            $stats .= "- keine - ";
        }
        $stats .= "</pre>";

        // Send mail
        TB_Server_Utils_Mail::sendStats(
            $stats
        );

    }

    /**
     * Send log files via email
     */
    protected function sendLogs() {
        // Get content of logs
        $errorLogger = TB_Server_Utils_Log::get();
        $cronLogger  = TB_Server_Utils_Log::getCron();

        // Send mail
        TB_Server_Utils_Mail::sendLogs(
            $errorLogger->getContent() . "\n\n" . $cronLogger->getContent()
        );

        // Truncate
        $errorLogger->clearLogfile();
        $cronLogger->clearLogfile();
    }

}

$cron = new TB_Server_Cron_DailyWorker();
$cron->execute();