<?php
/**
 * DEMO-Login
 * 
 * @author  Hamid Mergan (base functionality)
 *          <->
 *          Max Sternitzke (extended Demo-Login)
 */
class Trainingssystem_Plugin_Module_Demo_Login
{
    /**
     * Register Cronjobs
     */
    public function __construct() {
		add_action('wp', array($this, 'maybe_delete_demouser'));

		add_action('tspv2_demologin_delete_user', array($this, 'maybeDeleteDemoUser'));
	}

    /**
     * Triggered on each request.
     * Lookup if schedule is due to be executed
     */
	public function maybe_delete_demouser()
	{
		if (!wp_next_scheduled('tspv2_demologin_delete_user')) {
			wp_schedule_event(current_time('timestamp'), 'hourly', 'tspv2_demologin_delete_user');
		}
	}

    /**
     * CRON
     * 
     * Delete all demo-users with a registered-date x hours after login
     */
    public function maybeDeleteDemoUser() {
        $user_args = array(
            'meta_key' => 'demo_user',
            'meta_value' => '0',
            'meta_compare' => '>=',
            'number' => -1
        );
        $user_query = new WP_User_Query($user_args);

        $settings = get_option(TRAININGSSYSTEM_PLUGIN_SETTINGS);
        $deleteAfterHours = 12;

        if(isset($settings['demologin_autodelete']) && !empty($settings['demologin_autodelete']) && is_numeric($settings['demologin_autodelete'])) {
            $deleteAfterHours = $settings['demologin_autodelete'];
        }
        
        foreach($user_query->get_results() as $demouser) {
            
            $registrationDate = new DateTime($demouser->user_registered);
            $now = new DateTime();

            $diff = $now->diff($registrationDate);

            $hoursSinceRegister = $diff->h;
            $hoursSinceRegister = $hoursSinceRegister + ($diff->days*24);
            
            if($hoursSinceRegister >= $deleteAfterHours) {
                wp_delete_user( $demouser->ID );
            }
        }
    }

    /**
     * FRONTEND
     * 
     * Shows the Demo-Login-Button
     * Differs between single demo-login and extended demo-login
     * 
     * @return HTML-Code
     */
    public function showDemoLogin($atts)
    {
        // Manually Trigger delete process to free capacity
        $this->maybeDeleteDemoUser();

        if (0 == get_current_user_id()) {
            $twig = Trainingssystem_Plugin_Twig::getInstance()->twig;

            $extended = false;
            if(isset($atts['extended']) && $atts['extended'] == "true") {
                $extended = true;
            }

            if (!isset($atts['titel']) || trim($atts['titel']) == "") {
                $titel = 'Zur Demo-Version';
            } else {
                $titel = $atts['titel'];
            }

            $redirect = get_site_url();
            if (isset($atts['redirect']) && trim($atts['redirect']) != "") {
                $redirect = $atts['redirect'];
            }

            if($extended) {

                $settings = get_option(TRAININGSSYSTEM_PLUGIN_SETTINGS);

                if(isset($settings['demologin_registerkey']) && $settings['demologin_registerkey'] != "" && $settings['demologin_registerkey'] != 0) {

                    $user_args = array(
                        'meta_key' => 'demo_user',
                        'meta_value' => '1',
                        'meta_compare' => '=',
                        'number' => -1
                    );
                    $user_query = new WP_User_Query($user_args);
                    
                    $currentAccounts = count($user_query->get_results());

                    $demologin_registerkey = Trainingssystem_Plugin_Database::getInstance()->RegisterKey->getCodeDetails($settings['demologin_registerkey']);
                    
                    $maxAccounts = 1;
                    if(isset($settings['demologin_maxaccounts']) && !empty($settings['demologin_maxaccounts']) && is_numeric($settings['demologin_maxaccounts'])) {
                        $maxAccounts = $settings['demologin_maxaccounts'];
                    }

                    $privacy_terms_URL = "";
                    if (!empty($settings['privacy_terms_URL'])){
                        $privacy_terms_URL = $settings['privacy_terms_URL'];
                    }
                    
                    if($currentAccounts < $maxAccounts && !is_null($demologin_registerkey) && $demologin_registerkey->getCountCode() < $demologin_registerkey->getMaxCount()) {
                        return $twig->render('login-logout/demo-login.html', ["titel" => $titel,
                                "mode" => "extended",
                                "redirect" => $redirect,
                                "privacy_terms_URL" => $privacy_terms_URL,
                                "website_name" => get_bloginfo()
                            ]);
                    } else {
                        return $twig->render("login-logout/demo-login-extended-full.html");
                    }
                } else {
                    return $twig->render("login-logout/demo-login-extended-error.html");
                }

                
            } else {
                if (isset($atts['id']) && trim($atts['id']) != "") {
                    $id = $atts['id'];

                    $demo_user = get_user_by( "ID", $atts['id'] );
                    if($demo_user === false) {
                        return $twig->render("login-logout/demo-login-error.html");
                    }

                    return $twig->render('login-logout/demo-login.html', ["titel" => $titel,
                        "mode" => "single",
                        "redirect" => $redirect,
                        "id" => $id,
                    ]);
                } else {
                    return $twig->render("login-logout/demo-login-error.html");
                }
            }
        }
    }

    /**
     * FRONTEND
     * Displays the account takeover form for a demo user
     * 
     * @return HTML-Code
     */
    public function showDemoLoginTakeoverForm($atts) {
        $twig = Trainingssystem_Plugin_Twig::getInstance()->twig;

        if (0 !== get_current_user_id()) {

            $currentUser = wp_get_current_user();

            if($currentUser->demo_user == "1") { // demo user

                $pretext = null;
                if(isset($atts['pretext']) && trim($atts['pretext']) != "") {
                    $pretext = $atts['pretext'];
                }

                $headline = null;
                if(isset($atts['headline']) && trim($atts['headline']) != "") {
                    $headline = $atts['headline'];
                }

                $buttonText = "Account übernehmen";
                if(isset($atts['buttontext']) && trim($atts['buttontext']) != "") {
                    $buttonText = $atts['buttontext'];
                }

                $successText = "Account-Übernahme erfolgreich! Bitte E-Mails prüfen.";
                if(isset($atts['successtext']) && trim($atts['successtext']) != "") {
                    $successText = $atts['successtext'];
                }

                return $twig->render("login-logout/demo-login-takeover.html", [
                    "pretext"  => $pretext,
                    "headline" => $headline,
                    "buttonText" => $buttonText,
                    "successText" => $successText,
                    "rand" => uniqid(),
                ]);
            } elseif($currentUser->demo_user == "0") { // demo user, but not yet confirmed
                return $twig->render("login-logout/demo-login-takeover-notyetconfirmed.html");
            } else { // no demo-user at all
                return "";
            }
        } else {
            return $twig->render('modal-unauth.html', ["title" => get_bloginfo('name'), "url" => get_site_url(), "modalid" => uniqid()]);
        }
    }

    /**
     * FRONTEND 
     * Shortcode, that only displays content for guests (= not logged in)
     * 
     * @return HTML-Code
     */
    public function onlyForGuests($atts, $content = null) {
        if(0 === get_current_user_id()) {
            return do_shortcode($content);
        }
    }
    
    /**
     * FRONTEND 
     * Shortcode, that only displays content for users (= logged in)
     * 
     * @return HTML-Code
     */
    public function onlyForUser($atts, $content = null) {
        if(0 !== get_current_user_id()) {
            return do_shortcode($content);
        }
    }

    /**
     * AJAX
     * Called via ajax when button is clicked
     * performs background checks and sets the auth cookie
     */
    public function demo_user()
    {
        if (0 === get_current_user_id()) {
            if(isset($_POST['mode']) && $_POST['mode'] == "single" && isset($_POST['userid']) && !empty($_POST['userid']) && is_numeric($_POST['userid'])) {
                $userid = intval(sanitize_text_field($_POST['userid']));
                $demo_user = get_user_by( "ID", $userid);
                if($demo_user !== false) {
                    wp_set_auth_cookie($userid);
                    update_user_meta($userid, 'can_save', 0);
                    echo "1";
                }
            } elseif(isset($_POST['mode']) && $_POST['mode'] == "extended") {

                $settings = get_option(TRAININGSSYSTEM_PLUGIN_SETTINGS);

                $user_args = array(
                    'meta_key' => 'demo_user',
                    'meta_value' => '1',
                    'meta_compare' => '=',
                    'number' => -1
                );
                $user_query = new WP_User_Query($user_args);
                
                $currentAccounts = count($user_query->get_results());

                if($currentAccounts < $settings['demologin_maxaccounts']) {

                    $username = bin2hex(random_bytes(16));
                    $password = wp_generate_password(10, true, true);
                    $mail = $username . "@".get_bloginfo( 'name' ).".demouser";
                    $creation = wp_create_user($username, $password, $mail);

                    if (!is_wp_error($creation)) {

                        if (!empty($settings['privacy_terms_URL'])){
                            update_user_meta($creation, 'privacy_terms_confirmed', date("d.m.Y"));
                        }

                        $registerKey = new Trainingssystem_Plugin_Module_Register_Key();
                        if($registerKey->redeemRegisterkey($creation, $settings['demologin_registerkey'], false)) {
                            add_user_meta( $creation, "demo_user", "1");
                            Trainingssystem_Plugin_Database::getInstance()->LastLoginDao->save($creation);
                            wp_set_auth_cookie($creation);
                            echo "1";
                        } else {
                            echo "0";
                        }
                        
                    } else {
                        echo $creation->get_error_message();
                    }
                } else {
                    echo "full";
                }
            }
        }
        wp_die();
    }

    /**
     * AJAX
     * 
     * Called when account takeover form is being submitted
     * Reverts demo_user meta entry to 0, sets name and email, sends email to set password
     * 
     * @return "1" on success, other string instead
     */
    public function accountTakeover() {
        global $wpdb;

        if(isset($_POST['mail']) && trim($_POST['mail']) !== "" &&
            isset($_POST['username']) && trim($_POST['username']) !== "") {

            $username = sanitize_text_field($_POST['username']);
            $mail = sanitize_email($_POST['mail']);

            $user_by_username = get_user_by('login', $username);
            if($user_by_username === false) {
             
                $user_by_mail = get_user_by('email', $mail);

                if($user_by_mail === false) {
                    
                    $currentUser = wp_get_current_user();

                    if($currentUser->demo_user == "1") {

                        if($wpdb->update(
                            $wpdb->users, 
                            array(
                                'user_email' => $mail, 
                                'user_login' => $username, 
                                'user_nicename' => $username, 
                                'display_name' => $username
                            ), 
                            array(
                                'ID' => $currentUser->ID
                            )
                        )) {
                            if(update_user_meta($currentUser->ID, 'demo_user', "0") && update_user_meta($currentUser->ID, 'nickname', $username)) {
                                clean_user_cache( $currentUser->ID );
                                wp_new_user_notification( $currentUser->ID, null, 'both' );
                                Trainingssystem_Plugin_Database::getInstance()->LastLoginDao->save($currentUser->ID);
                                wp_set_auth_cookie($currentUser->ID);
                                echo "1";
                            } else {
                                echo "update meta failed";
                            }
                        } else {
                            echo "error updating db";
                        }

                    } else {
                        echo "no demo user!";
                    }
                } else {
                    echo "mail";
                }
            } else {
                echo "username";
            }
        }
        wp_die();
    }

    /**
     * ACTION-HOOK
     * 
     * Fires when user changes its password.
     * Used to delete demo_user user meta entry if it exists
     */
    public function passwordChanged($user, $newPasswd) {
        $demoUser = get_user_meta($user->ID, "demo_user", true);
        
        if($demoUser == "0") {
            delete_user_meta($user->ID, "demo_user");
        }
    }
}
