<?php

class JobsearchXingLogin {

    private $xing_details;
    private $redirect_url;
    private $state_token;

    public function __construct() {
        add_shortcode('jobsearch_xing_login', array($this, 'display_login_button'));
        add_action('wp_ajax_jobsearch_xing_response_data', array($this, 'jobsearch_xing_response_data_callback'));
        add_action('wp_ajax_nopriv_jobsearch_xing_response_data', array($this, 'jobsearch_xing_response_data_callback'));
        add_action('jobsearch_do_apply_job_xing', array($this, 'do_apply_job_with_xing'), 10, 1);
        add_action('jobsearch_apply_job_with_xing', array($this, 'apply_job_with_xing'), 10, 1);
        add_action('wp_ajax_jobsearch_applying_job_with_xing', array($this, 'applying_job_with_xing'));
        add_action('wp_ajax_nopriv_jobsearch_applying_job_with_xing', array($this, 'applying_job_with_xing'));
        
        $this->state_token = $this->generate_state_token();
    }

    private function generate_state_token() {
        if (!isset($_SESSION['xing_state_token'])) {
            $_SESSION['xing_state_token'] = bin2hex(random_bytes(16));
        }
        return $_SESSION['xing_state_token'];
    }

    public function jobsearch_xing_response_data_callback() {
        global $jobsearch_plugin_options;
        
        $nonce_val = sanitize_key(wp_unslash($_POST['_nonce']));
        if (!wp_verify_nonce($nonce_val, 'jobsearch_ajax_nonce')) {
            wp_send_json_error(esc_html__('You are not allowed to do this.', 'wp-jobsearch'));
        }

        // Validate state token
        if (!isset($_POST['state']) || !hash_equals($this->state_token, $_POST['state'])) {
            wp_send_json_error(esc_html__('Invalid state token', 'wp-jobsearch'));
        }

        $candidate_auto_approve = isset($jobsearch_plugin_options['candidate_auto_approve']) ? $jobsearch_plugin_options['candidate_auto_approve'] : '';

        $user_data = isset($_POST['user_data']) ? wp_unslash($_POST['user_data']) : '';
        $xing_user = json_decode(stripslashes($user_data), true);
        
        if (!is_array($xing_user) || empty($xing_user['id'])) {
            wp_send_json_error(esc_html__('Invalid user data', 'wp-jobsearch'));
        }

        $oauth_token = isset($_POST['oauth_token']) ? sanitize_text_field($_POST['oauth_token']) : '';
        if (!$this->validate_xing_oauth_token($oauth_token, $xing_user['id'])) {
            wp_send_json_error(esc_html__('Invalid Xing token', 'wp-jobsearch'));
        }

        $user_dashboard_page = isset($jobsearch_plugin_options['user-dashboard-template-page']) ? 
            jobsearch__get_post_id($jobsearch_plugin_options['user-dashboard-template-page'], 'page') : 0;
        $real_redirect_url = $this->get_safe_redirect_url();

        $json_arr = array(
            'redirect_url' => $real_redirect_url,
            'status' => true
        );

        $this->xing_details = $xing_user;
        $user_image = isset($xing_user['photo_urls']['maxi_thumb']) ? esc_url_raw($xing_user['photo_urls']['maxi_thumb']) : '';
        $job_title = isset($xing_user['professional_experience']['primary_company']['title']) ? 
            sanitize_text_field($xing_user['professional_experience']['primary_company']['title']) : '';

        $user_id = $xing_user['id'];
        $wp_users = get_users(array(
            'meta_key' => 'jobsearch_xing_id',
            'meta_value' => $user_id,
            'number' => 1,
            'count_total' => false,
            'fields' => 'id',
        ));

        if (empty($wp_users[0])) {
            $first_name = isset($xing_user['first_name']) ? sanitize_text_field($xing_user['first_name']) : '';
            $last_name = isset($xing_user['last_name']) ? sanitize_text_field($xing_user['last_name']) : '';
            $email = isset($xing_user['active_email']) ? sanitize_email($xing_user['active_email']) : '';

            if (!is_email($email)) {
                wp_send_json_error(esc_html__('Invalid email address', 'wp-jobsearch'));
            }

            $_social_user_obj = get_user_by('email', $email);
            if (!empty($_social_user_obj)) {
                wp_send_json_error(__('This email is already registered', 'wp-jobsearch'));
            }

            $username = '';
            if (!empty($first_name) && !empty($last_name)) {
                $username = sanitize_user(str_replace(' ', '_', strtolower($first_name . '_' . $last_name)));
            } else {
                $username = sanitize_user(str_replace(array('@', '.'), '_', $email));
            }

            if (username_exists($username)) {
                $username .= '_' . bin2hex(random_bytes(2));
            }

            $user_pass = wp_generate_password(16, true, true);
            $new_user = wp_create_user($username, $user_pass, $email);

            if (is_wp_error($new_user)) {
                wp_send_json_error($new_user->get_error_message());
            }

            $user_candidate_id = jobsearch_get_user_candidate_id($new_user);
            $user_role = 'jobsearch_candidate';
            wp_update_user(array('ID' => $new_user, 'role' => $user_role));
            
            update_user_meta($new_user, 'first_name', $first_name);
            update_user_meta($new_user, 'jobsearch_xing_id', $user_id);
            
            $candidate_id = get_user_meta($new_user, 'jobsearch_candidate_id', true);
            update_post_meta($candidate_id, 'jobsearch_field_candidate_jobtitle', $job_title);
            
            if ($candidate_auto_approve == 'on' || $candidate_auto_approve == 'email') {
                update_post_meta($user_candidate_id, 'jobsearch_field_candidate_approved', 'on');
            }
            
            $c_user = get_user_by('ID', $new_user);
            do_action('jobsearch_new_user_register', $c_user, $user_pass);
            wp_set_auth_cookie($new_user, false, is_ssl());
        } else {
            wp_set_auth_cookie($wp_users[0], false, is_ssl());
        }
        
        wp_send_json_success($json_arr);
    }

    private function validate_xing_oauth_token($token, $xing_user_id) {
        if (empty($token) || empty($xing_user_id)) {
            return false;
        }

        $api_url = "https://api.xing.com/v1/users/me";
        $args = [
            'headers' => [
                'Authorization' => 'Bearer ' . $token,
            ],
            'timeout' => 15,
        ];
        
        $response = wp_remote_get($api_url, $args);
        
        if (is_wp_error($response)) {
            return false;
        }

        $response_code = wp_remote_retrieve_response_code($response);
        if ($response_code !== 200) {
            return false;
        }

        $body = json_decode(wp_remote_retrieve_body($response), true);
        return (isset($body['users'][0]['id']) && hash_equals($body['users'][0]['id'], $xing_user_id));
    }

    private function get_safe_redirect_url() {
        global $jobsearch_plugin_options;
        
        $default_url = home_url('/');
        $user_dashboard_page = isset($jobsearch_plugin_options['user-dashboard-template-page']) ? 
            jobsearch__get_post_id($jobsearch_plugin_options['user-dashboard-template-page'], 'page') : 0;
        $default_url = $user_dashboard_page > 0 ? get_permalink($user_dashboard_page) : $default_url;

        if (isset($_COOKIE['xing_redirect_url']) && $_COOKIE['xing_redirect_url'] != '') {
            $redirect_url = esc_url_raw($_COOKIE['xing_redirect_url']);
            if (wp_validate_redirect($redirect_url, $default_url) === $redirect_url) {
                unset($_COOKIE['xing_redirect_url']);
                setcookie('xing_redirect_url', null, -1, '/', COOKIE_DOMAIN, is_ssl(), true);
                return $redirect_url;
            }
        }

        return apply_filters('jobsearch_after_social_login_redirect_url', $default_url, 'xing');
    }

    public function display_login_button() {
        global $jobsearch_plugin_options;
        $rand_id = rand(10000000, 99999999);
        $admin_ajax_url = admin_url('admin-ajax.php');
        $jobsearch_xing_consumer_key = isset($jobsearch_plugin_options['jobsearch_xing_consumer_key']) ? 
            $jobsearch_plugin_options['jobsearch_xing_consumer_key'] : '';
        
        ob_start();
        if (!empty($jobsearch_xing_consumer_key)) {
            echo '<script type="xing/login">{"consumer_key": "' . esc_js($jobsearch_xing_consumer_key) . '","size": "xlarge"}</script>';
        }
        $Button_Data = ob_get_clean();
        ?>
        <li id="jobsearch-xing-wrapper" style="position: relative;">
            <script>
                jQuery(document).ready(function () {
                    var setCusCss<?php echo ($rand_id); ?> = setInterval(function () {
                        var $iframe<?php echo ($rand_id); ?> = jQuery('#xing-dynam-btn<?php echo ($rand_id); ?>').find('iframe');
                        $iframe<?php echo ($rand_id); ?>.attr('id', 'xing_frame_<?php echo ($rand_id); ?>');
                        $iframe<?php echo ($rand_id); ?>.attr('name', 'xing_frame_<?php echo ($rand_id); ?>');
                        $iframe<?php echo ($rand_id); ?>.css({'width': '100%', 'opacity': '0'});
                        $iframe<?php echo ($rand_id); ?>.attr('width', '100%');
                        clearInterval(setCusCss<?php echo ($rand_id); ?>);
                    }, 2000);
                });
                function onXingAuthLogin(xing_response) {
                    if (xing_response.error && xing_response.user != null) {
                        alert(xing_response.error);
                    } else {
                        if (xing_response.user != 'undefined' && xing_response.user != null) {
                            var userStr = JSON.stringify(xing_response.user);
                            var dataString = 'action=jobsearch_xing_response_data&_nonce=' + jobsearch_comon_script_vars.nonce + 
                                '&user_data=' + encodeURIComponent(userStr) + '&oauth_token=' + encodeURIComponent(xing_response.oauth_token) + 
                                '&state=' + '<?php echo esc_js($this->state_token); ?>';
                            var ajax_url = '<?php echo esc_url($admin_ajax_url); ?>';
                            jQuery.ajax({
                                type: 'POST',
                                url: ajax_url,
                                dataType: "json",
                                data: dataString,
                                success: function (response) {
                                    if (response.status !== 'undefined' && response.status == true) {
                                        window.location.href = response.redirect_url;
                                    } else {
                                        alert(response.msg);
                                    }
                                }
                            });
                        }
                    }
                }
            </script>
            <div id="xing-dynam-btn<?php echo esc_attr($rand_id); ?>" class="xing-dynamic-btn" style="position: absolute; width: 96%; z-index: 999;"><?php echo $Button_Data; ?></div>
            <script>
                (function (d) {
                    var js, id = 'lwx';
                    if (d.getElementById(id))
                        return;
                    js = d.createElement('script');
                    js.id = id;
                    js.src = "https://www.xing-share.com/plugins/login.js";
                    d.getElementsByTagName('head')[0].appendChild(js)
                }(document));
            </script>

            <a id="jobsearch-xing-login" class="jobsearch-xing-bg" href="javascript:void(0);"><i class="fa fa-xing"></i><?php echo esc_html__('Login with Xing', 'wp-jobsearch') ?></a>
        </li>
        <?php
    }
    
    public function do_apply_job_with_xing($user_id) {
        global $jobsearch_plugin_options;

        $candidate_auto_approve = isset($jobsearch_plugin_options['candidate_auto_approve']) ? $jobsearch_plugin_options['candidate_auto_approve'] : '';
        $user_is_candidate = jobsearch_user_is_candidate($user_id);

        $apply_job_cond = true;
        if ($candidate_auto_approve != 'on') {
            $apply_job_cond = false;
            if ($user_is_candidate) {
                $candidate_id = jobsearch_get_user_candidate_id($user_id);
                $candidate_status = get_post_meta($candidate_id, 'jobsearch_field_candidate_approved', true);
                if ($candidate_status == 'on') {
                    $apply_job_cond = true;
                }
            }
        }
        if ($candidate_auto_approve == 'email') {
            $apply_job_cond = true;
        }

        if (isset($_COOKIE['jobsearch_apply_xing_jobid']) && is_numeric($_COOKIE['jobsearch_apply_xing_jobid'])) {
            $job_id = intval($_COOKIE['jobsearch_apply_xing_jobid']);

            if ($user_is_candidate && $apply_job_cond) {
                $candidate_id = jobsearch_get_user_candidate_id($user_id);

                $alredy_aplied_job = false;
                jobsearch_create_user_meta_list($job_id, 'jobsearch-user-jobs-applied-list', $user_id);
                $job_applicants_list = get_post_meta($job_id, 'jobsearch_job_applicants_list', true);
                if ($job_applicants_list != '') {
                    $job_applicants_list = explode(',', $job_applicants_list);
                    if (!in_array($candidate_id, $job_applicants_list)) {
                        $job_applicants_list[] = $candidate_id;
                    } else {
                        $alredy_aplied_job = true;
                    }
                    $job_applicants_list = implode(',', $job_applicants_list);
                } else {
                    $job_applicants_list = $candidate_id;
                }
                update_post_meta($job_id, 'jobsearch_job_applicants_list', $job_applicants_list);
                $c_user = get_user_by('ID', $user_id);
                if ($alredy_aplied_job === false) {
                    do_action('jobsearch_job_applied_to_employer', $c_user, $job_id);
                    do_action('jobsearch_job_applied_to_candidate', $c_user, $job_id);
                }
            }

            unset($_COOKIE['jobsearch_apply_xing_jobid']);
            setcookie('jobsearch_apply_xing_jobid', null, -1, '/', COOKIE_DOMAIN, is_ssl(), true);
        }
    }

    public function applying_job_with_xing() {
        global $jobsearch_plugin_options;

        $nonce_val = sanitize_key(wp_unslash($_POST['_nonce']));
        if (!wp_verify_nonce($nonce_val, 'jobsearch_ajax_nonce')) {
            wp_send_json_error(esc_html__('You are not allowed to do this.', 'wp-jobsearch'));
        }
        
        $candidate_auto_approve = isset($jobsearch_plugin_options['candidate_auto_approve']) ? $jobsearch_plugin_options['candidate_auto_approve'] : '';
        $job_id = isset($_POST['job_id']) ? intval($_POST['job_id']) : 0;
        
        if ($job_id <= 0 || get_post_type($job_id) !== 'job') {
            wp_send_json_error(esc_html__('Invalid job ID', 'wp-jobsearch'));
        }

        setcookie('jobsearch_apply_xing_jobid', $job_id, time() + 180, "/", COOKIE_DOMAIN, is_ssl(), true);
        if ($candidate_auto_approve == 'on') {
            $real_redirect_url = get_permalink($job_id);
            setcookie('xing_redirect_url', $real_redirect_url, time() + 360, "/", COOKIE_DOMAIN, is_ssl(), true);
        }

        wp_send_json_success(array('redirect_url' => admin_url('admin-ajax.php?action=jobsearch_xing')));
    }

    public function apply_job_with_xing($args = array()) {
        global $jobsearch_plugin_options;
        
        $rand_id = rand(10000000, 99999999);
        $admin_ajax_url = admin_url('admin-ajax.php');
        $jobsearch_xing_consumer_key = isset($jobsearch_plugin_options['jobsearch_xing_consumer_key']) ? 
            $jobsearch_plugin_options['jobsearch_xing_consumer_key'] : '';
        $xing_login = isset($jobsearch_plugin_options['xing-social-login']) ? $jobsearch_plugin_options['xing-social-login'] : '';
        
        if ($jobsearch_xing_consumer_key == '' || $xing_login != 'on') {
            return;
        }

        ob_start();
        if (!empty($jobsearch_xing_consumer_key)) {
            echo '<script type="xing/login">{"consumer_key": "' . esc_js($jobsearch_xing_consumer_key) . '","size": "xlarge"}</script>';
        }
        $Button_Data = ob_get_clean();
        
        $job_id = isset($args['job_id']) ? intval($args['job_id']) : 0;
        $classes = isset($args['classes']) && !empty($args['classes']) ? esc_attr($args['classes']) : 'jobsearch-applyjob-xing-btn';
        $label = isset($args['label']) ? esc_html($args['label']) : '';
        $view = isset($args['view']) ? esc_attr($args['view']) : '';

        ob_start();
        ?>
        <script>
            jQuery(document).ready(function () {
                var setCusCss<?php echo ($rand_id); ?> = setInterval(function () {
                    var $iframe<?php echo ($rand_id); ?> = jQuery('#xing-dynam-btn<?php echo ($rand_id); ?>').find('iframe');
                    $iframe<?php echo ($rand_id); ?>.attr('id', 'xing_frame_<?php echo ($rand_id); ?>');
                    $iframe<?php echo ($rand_id); ?>.attr('name', 'xing_frame_<?php echo ($rand_id); ?>');
                    $iframe<?php echo ($rand_id); ?>.css({'width': '100%', 'opacity': '0'});
                    $iframe<?php echo ($rand_id); ?>.attr('width', '100%');
                    clearInterval(setCusCss<?php echo ($rand_id); ?>);
                }, 2000);
            });
            function onXingAuthLogin(xing_response) {
                if (xing_response.error && xing_response.user != null) {
                    alert(xing_response.error);
                } else {
                    if (xing_response.user != 'undefined' && xing_response.user != null) {
                        var userStr = JSON.stringify(xing_response.user);
                        var dataString = 'action=jobsearch_xing_response_data&_nonce=' + jobsearch_comon_script_vars.nonce + 
                            '&user_data=' + encodeURIComponent(userStr) + '&oauth_token=' + encodeURIComponent(xing_response.oauth_token) + 
                            '&state=' + '<?php echo esc_js($this->state_token); ?>';
                        var ajax_url = '<?php echo esc_url($admin_ajax_url); ?>';
                        jQuery.ajax({
                            type: 'POST',
                            url: ajax_url,
                            dataType: "json",
                            data: dataString,
                            success: function (response) {
                                if (response.status !== 'undefined' && response.status == true) {
                                    window.location.href = response.redirect_url;
                                } else {
                                    alert(response.msg);
                                }
                            }
                        });
                    }
                }
            }
        </script>
        <div id="xing-dynam-btn<?php echo esc_attr($rand_id); ?>" class="xing-dynamic-btn" style="position: absolute; width: 96%; z-index: 999;"><?php echo $Button_Data; ?></div>
        <script>
            (function (d) {
                var js, id = 'lwx';
                if (d.getElementById(id))
                    return;
                js = d.createElement('script');
                js.id = id;
                js.src = "https://www.xing-share.com/plugins/login.js";
                d.getElementsByTagName('head')[0].appendChild(js)
            }(document));
        </script>
        <?php
        $xing_script = ob_get_clean();
        
        switch ($view) {
            case 'job2':
                echo '<a href="javascript:void(0);" class="' . $classes . '" data-id="' . esc_attr($job_id) . '">' . $label . $xing_script . '</a>';
                break;
            case 'job3':
                echo '<li><a href="javascript:void(0);" class="' . $classes . '" data-id="' . esc_attr($job_id) . '"></a>' . $xing_script . '</li>';
                break;
            case 'job4':
                echo '<a href="javascript:void(0);" class="' . $classes . '" data-id="' . esc_attr($job_id) . '"><i class="fa fa-xing"></i> ' . esc_html__('Apply with Xing', 'wp-jobsearch') . $xing_script . '</a>';
                break;
            case 'job5':
                echo '<a href="javascript:void(0);" class="' . $classes . '" data-id="' . esc_attr($job_id) . '"><i class="fa fa-xing"></i>' . $label . '</a>' . $xing_script;
                break;
            case 'job6':
                echo '<li><a href="javascript:void(0);" class="' . $classes . '" data-id="' . esc_attr($job_id) . '"><i class="fa fa-xing"></i>' . $label . '</a>' . $xing_script . '</li>';
                break;
            default:
                echo '<li><a href="javascript:void(0);" class="' . $classes . '" data-id="' . esc_attr($job_id) . '"><i class="fa fa-xing"></i> ' . esc_html__('Xing', 'wp-jobsearch') . '</a>' . $xing_script . '</li>';
        }
    }
}

new JobsearchXingLogin();