<?php
/*
Plugin Name: Social Login & Registration
Plugin URI: https://wedevs.com/docs/wp-user-frontend-pro/modules/social-login-registration/
Thumbnail Name: Social-Media-Login.png
Description: Add Social Login and registration feature in WP User Frontend
Version: 1.1
Author: weDevs
Author URI: http://wedevs.com/
License: GPL2
*/

/**
 * Copyright (c) 2017 weDevs ( email: info@wedevs.com ). All rights reserved.
 *
 * Released under the GPL license
 * http://www.opensource.org/licenses/gpl-license.php
 *
 * This is an add-on for WordPress
 * http://wordpress.org/
 *
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * **********************************************************************
 */

// don't call the file directly
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * WPUF_Social_Login
 *
 * @class WPUF_Social_Login The class that holds the entire WPUF_Social_Login plugin
 */

use Hybridauth\Exception\Exception;
use Hybridauth\Hybridauth;
use Hybridauth\HttpClient;
use Hybridauth\Storage\Session;

class WPUF_Social_Login {

    private $account_page_url = null;
    private $access_token;
    private $form_id;
    private $provider;
    private $config;

    /**
     * Load automatically when class instantiated
     *
     * @since 2.4
     *
     * @uses actions|filter hooks
     */
    public function __construct() {
        if ( ! class_exists( 'Hybridauth' ) ) {
            if ( class_exists( 'WeDevs_Dokan' ) && class_exists( 'Dokan_Pro' ) ) {
                if ( version_compare( DOKAN_PRO_PLUGIN_VERSION, '3.0.0', '<' ) ) {
                    require_once DOKAN_PRO_INC . '/lib/hybridauth/autoload.php';
                }
            } else {
                require_once dirname( __FILE__ ) . '/lib/hybridauth/autoload.php';
            }
        }

        // Include our custom Facebook provider
        require_once dirname( __FILE__ ) . '/custom-facebook-provider.php';

        add_action( 'setup_theme', array( $this, 'set_account_page_url' ) );
        add_action( 'admin_notices', array( $this, 'show_admin_notice' ) );
        add_filter( 'wpuf_settings_sections', array( $this, 'wpuf_social_settings_tab' ) );
        add_filter( 'wpuf_settings_fields', array( $this, 'wpuf_pro_social_api_fields' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 9 );

        //Hybrid auth action
        add_action( 'template_redirect', array( $this, 'monitor_authentication_requests' ) );

        // add social buttons on registration form
        add_action( 'wpuf_login_form_bottom', array( $this, 'render_social_logins' ) );
        add_action( 'wpuf_reg_form_bottom', array( $this, 'render_social_logins' ) );
        add_action( 'wpuf_add_profile_form_bottom', array( $this, 'render_social_logins' ) );
    }

    /**
     * Instantiate the class
     *
     * @return object
     * @since 2.6
     */
    public static function init() {
        static $instance = false;

        if ( ! $instance ) {
            $instance = new WPUF_Social_Login();
        }

        return $instance;
    }

    /**
     * Check if current page is WPUF Account page
     *
     * @since 3.2.0
     *
     * @return bool
     */
    public function is_account_page() {
        global $post;

        $account_page_id = wpuf_get_option( 'account_page', 'wpuf_my_account', 0 );

        return ! empty( $post->ID ) && absint( $account_page_id ) === $post->ID;
    }

    /**
     * Set account page URL
     *
     * @since 3.3.0
     *
     * @return void
     */
    public function set_account_page_url() {
        $account_page_id = wpuf_get_option( 'account_page', 'wpuf_my_account', 0 );

        if ( ! empty( $account_page_id ) ) {
            $this->account_page_url = get_permalink( $account_page_id );

            // For Facebook apps, ensure HTTPS for callback URL
            if ( is_ssl() || ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) ||
                 ( isset( $_SERVER['HTTP_X_FORWARDED_SSL'] ) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'on' ) ) {
                $this->account_page_url = str_replace( 'http://', 'https://', $this->account_page_url );
            } else {
                // Force HTTPS for Facebook since it requires it
                $this->account_page_url = str_replace( 'http://', 'https://', $this->account_page_url );
            }

            $this->config = $this->get_providers_config();
        }
    }

    /**
     * Show admin notice if account page is not set in settings
     *
     * @since 3.3.0
     *
     * @return void
     */
    public function show_admin_notice() {
        if ( empty( $this->account_page_url ) ) {
            ?>
                <div class="error">
                    <p><?php esc_html_e( 'To use WPUF Social Login module, please set your account page in My Account > Account Page settings first.', 'wpuf-pro' ); ?></p>
                </div>
            <?php
        }
    }

    /**
     * Register all scripts
     *
     * @return void
     **/
    public function enqueue_scripts() {
        // register modern social login styles and scripts
        wp_enqueue_style( 'wpuf-modern-social-style', WPUF_PRO_ASSET_URI . '/css/modern-social-login.css', array(), WPUF_VERSION );
        wp_enqueue_script( 'wpuf-modern-social-script', WPUF_PRO_ASSET_URI . '/js/modern-social-login.js', array( 'jquery' ), WPUF_VERSION, true );
    }

    /**
     * Get configuration values for HybridAuth
     *
     * @return array
     */
    private function get_providers_config() {
        $config = [
            'callback'  => $this->account_page_url,
            'providers' => [
                'Google'    => [
                    'enabled' => true,
                    'keys'    => [
                        'id' => '',
                        'secret' => '',
                    ],
                    'scope'   => 'openid email profile',
                ],
                'Facebook'  => [
                    'enabled'        => true,
                    'keys'           => [
                        'id' => '',
                        'secret' => '',
                    ],
                    'trustForwarded' => false,
                    'scope'          => 'email, public_profile',
                ],
                'Twitter'   => [
                    'enabled'      => true,
                    'keys'         => [
                        'key' => '',
                        'secret' => '',
                    ],
                    'includeEmail' => true,
                ],
                'LinkedIn'  => [
                    'enabled' => true,
                    'keys'    => [
                        'id' => '',
                        'secret' => '',
                    ],
                    'scope'          => 'openid profile email',
                    'authorize_url'  => 'https://www.linkedin.com/oauth/v2/authorization',
                    'access_token_url' => 'https://www.linkedin.com/oauth/v2/accessToken',
                    'api_base_url'   => 'https://api.linkedin.com/v2/',
                    'oidc_issuer'    => 'https://www.linkedin.com/oauth',
                    'oidc_userinfo_endpoint' => 'https://api.linkedin.com/v2/userinfo',
                    'wrapper' => [
                        'class' => 'Hybridauth\\Provider\\LinkedIn',
                        'path'  => null
                    ]
                ],
                // 'Instagram' => [
                //     'enabled' => true,
                //     'keys'    => [
                //         'id' => '',
                //         'secret' => '',
                //     ],
                //     'scope'   => 'instagram_business_basic,instagram_business_manage_messages,instagram_business_manage_comments,instagram_business_content_publish',
                //     'authorize_url' => 'https://www.facebook.com/v18.0/dialog/oauth',
                //     'access_token_url' => 'https://graph.facebook.com/v18.0/oauth/access_token',
                //     'api_base_url' => 'https://graph.facebook.com/v18.0/',
                // ],
                'GitHub' => [
                    'enabled' => true,
                    'keys'    => [
                        'id' => '',
                        'secret' => '',
                    ],
                    'scope'   => 'user:email',
                    'authorize_url' => 'https://github.com/login/oauth/authorize',
                    'access_token_url' => 'https://github.com/login/oauth/access_token',
                    'api_base_url' => 'https://api.github.com/',
                ],
            ],
        ];

        //facebook config from admin
        $fb_id     = wpuf_get_option( 'fb_app_id', 'wpuf_social_api' );
        $fb_secret = wpuf_get_option( 'fb_app_secret', 'wpuf_social_api' );

        if ( $fb_id !== '' && $fb_secret !== '' ) {
            $config['providers']['Facebook']['keys']['id']     = $fb_id;
            $config['providers']['Facebook']['keys']['secret'] = $fb_secret;
            // Use our custom Facebook provider to fix the access token null issue
            $config['providers']['Facebook']['adapter'] = 'WPUF\\Social\\CustomFacebookProvider';
        }

        //google config from admin
        $g_id     = wpuf_get_option( 'google_app_id', 'wpuf_social_api' );
        $g_secret = wpuf_get_option( 'google_app_secret', 'wpuf_social_api' );

        if ( $g_id !== '' && $g_secret !== '' ) {
            $config['providers']['Google']['keys']['id']     = $g_id;
            $config['providers']['Google']['keys']['secret'] = $g_secret;
        }
        //linkedin config from admin
        $l_id     = wpuf_get_option( 'linkedin_app_id', 'wpuf_social_api' );
        $l_secret = wpuf_get_option( 'linkedin_app_secret', 'wpuf_social_api' );

        if ( $l_id !== '' && $l_secret !== '' ) {
            $config['providers']['LinkedIn']['keys']['id']     = $l_id;
            $config['providers']['LinkedIn']['keys']['secret'] = $l_secret;

            // Apply LinkedIn-specific configuration filter
            $linkedin_config = apply_filters( 'wpuf_linkedin_provider_config', $config['providers']['LinkedIn'] );
            $config['providers']['LinkedIn'] = $linkedin_config;
        }

        //Twitter config from admin
        $twitter_id     = wpuf_get_option( 'twitter_app_id', 'wpuf_social_api' );
        $twitter_secret = wpuf_get_option( 'twitter_app_secret', 'wpuf_social_api' );

        if ( $twitter_id !== '' && $twitter_secret !== '' ) {
            $config['providers']['Twitter']['keys']['key']    = $twitter_id;
            $config['providers']['Twitter']['keys']['secret'] = $twitter_secret;
        }

        //GitHub config from admin - PROFESSIONAL LICENSE ONLY
        // Only enable GitHub for Professional license users

        $github_id     = wpuf_get_option( 'github_app_id', 'wpuf_social_api' );
        $github_secret = wpuf_get_option( 'github_app_secret', 'wpuf_social_api' );

        if ( $github_id !== '' && $github_secret !== '' && $this->is_professional_license() ) {
            $config['providers']['GitHub']['keys']['id']     = $github_id;
            $config['providers']['GitHub']['keys']['secret'] = $github_secret;
        }

        /**
         * Filter the Config array of Hybridauth
         *
         * @param array $config
         *
         * @since 1.0.0
         */
        $config = apply_filters( 'wpuf_social_providers_config', $config );

        return $config;
    }

    /**
     * Monitors Url for Hauth Request and process Hybridauth for authentication
     *
     * @return void
     */
    public function monitor_authentication_requests() {
        if ( ! $this->is_account_page() ) {
            //sent error to user in case of not account page
            return;
        }

        // Initialize session storage first
        $storage = new Session();

        // Check if this is a normal account page visit (no social login intent)
        $provider_requested = ! empty( $_GET['wpuf_reg'] ) ? sanitize_text_field( wp_unslash( $_GET['wpuf_reg'] ) ) : '';
        $is_oauth_callback = isset( $_GET['code'] ) || isset( $_GET['oauth_token'] ) || isset( $_GET['oauth_verifier'] ) || isset( $_GET['state'] );

        // If no social login activity, clear any stale session data and exit
        if ( ! $provider_requested && ! $is_oauth_callback && ! $storage->get( 'provider' ) ) {
            return;
        }

        // If this is a normal account visit but there's stale session data, clean it up
        if ( ! $provider_requested && ! $is_oauth_callback && $storage->get( 'provider' ) ) {
            $storage->clear();
            return;
        }

        try {
            /**
             * Feed the config array to Hybridauth
             *
             * @var Hybridauth
             */
            $hybridauth = new Hybridauth( $this->config );

            /**
             * Hold information about provider when user clicks on Sign In.
             */
            $provider = $provider_requested;
            $form_id  = ! empty( $_GET['form_id'] ) ? sanitize_text_field( wp_unslash( $_GET['form_id'] ) ) : '';

            if ( $provider ) {
                $storage->set( 'provider', $provider );
                $storage->set( 'form_id', $form_id );
            }

            $provider = $storage->get( 'provider' );

            if ( $provider ) {

                // Check if GitHub requires Professional license
                /*
                if ( strtolower( $provider ) === 'github' && ! $this->is_professional_license() ) {
                    error_log( 'WPUF Social Login: GitHub login requires qualifying license' );
                    wp_die( __( 'GitHub login is only available for Professional, Business, Enterprise, or AppSumo lifetime license users. Please upgrade your license to use this feature.', 'wpuf-pro' ) );
                }
                */

                // Special handling for LinkedIn to use OpenID Connect
                if ( strtolower( $provider ) === 'linkedin' ) {
                    $adapter = $this->authenticate_linkedin_openid( $hybridauth );
                } else {
                    $adapter = $hybridauth->authenticate( $provider );
                }

                $access_token       = $adapter->getAccessToken();
                $this->provider     = $provider;

                // Handle both string and array formats for access token
                if ( is_array( $access_token ) ) {
                    $this->access_token = ! empty( $access_token['access_token'] ) ? $access_token['access_token'] : '';
                } else {
                    $this->access_token = $access_token ? $access_token : '';
                }
                $this->form_id      = $storage->get( 'form_id' );

                // For Facebook, let's also check what's stored in the adapter
                if ( $provider === 'Facebook' && method_exists( $adapter, 'getStoredDataPublic' ) ) {
                    $stored_token = $adapter->getStoredDataPublic('access_token');

                    // Check if user is connected
                    $is_connected = $adapter->isConnected();
                }
            }

            if ( ! isset( $adapter ) ) {
                return;
            }

            // Validate that we have a proper access token before proceeding
            if ( empty( $this->access_token ) && $this->provider !== 'LinkedIn' ) {
                wp_die( __( 'Authentication failed: Invalid access token received from social provider.', 'wpuf-pro' ) . '<br><br>' .
                       __( 'This usually means there was an issue during the OAuth process. Please try again.', 'wpuf-pro' ) );
            }

            // Check if we have a custom user profile (from LinkedIn OpenID Connect)
            if ( isset( $adapter->userProfile ) ) {
                $user_profile = $adapter->userProfile;
            } else {
                try {
                    $user_profile = $adapter->getUserProfile();

                    // Check if user profile is null
                    if ( $user_profile === null ) {
                        throw new Exception( 'Failed to retrieve user profile from ' . $this->provider . '. The OAuth process may not have completed successfully.' );
                    }

                    $from_obj = get_object_vars( $user_profile );

                    // Check if we got valid user data
                    if ( empty( $from_obj ) ) {
                        throw new Exception( 'Received empty user profile data from ' . $this->provider . '.' );
                    }

                    $user_profile = new stdClass();

                    array_map(
                        function ( $key, $val ) use ( &$user_profile ) {
                            $user_profile->{$this->camel_to_snake_case( $key )} = $val;
                        }, array_keys( $from_obj ), $from_obj
                    );

                    // Clear storage now that we have the user profile
                    $storage->clear();
                } catch ( Exception $profile_exception ) {
                    // Check for specific Facebook access token errors
                    if ( $this->provider === 'Facebook' && strpos( $profile_exception->getMessage(), 'getKidFromOLDCToken' ) !== false ) {
                        wp_die( __( 'Facebook authentication failed: Invalid access token.', 'wpuf-pro' ) . '<br><br>' .
                               __( 'This usually means there was an issue during the Facebook login process. Please try the following:', 'wpuf-pro' ) . '<br>' .
                               '1. Clear your browser cache and cookies<br>' .
                               '2. Make sure your Facebook App settings are correct<br>' .
                               '3. Try logging in again<br><br>' .
                               'Debug: ' . esc_html( $profile_exception->getMessage() ) );
                    }

                    // Clear storage in case of error to avoid session pollution
                    $storage->clear();

                    // Re-throw the exception to be handled by the outer catch blocks
                    throw $profile_exception;
                }
            }

            if ( ! $user_profile ) {
                wp_redirect( $this->account_page_url );
                exit;
            }

            if ( empty( $user_profile->email ) ) {
                // For Twitter and Instagram, email might not be available, so we can generate one or handle it differently
                if ( ! empty( $user_profile->identifier ) ) {
                    if ( $this->provider === 'Twitter' ) {
                        // Generate a placeholder email using the Twitter identifier
                        $user_profile->email = 'twitter_' . $user_profile->identifier . '@twitter-login.local';
                    } elseif ( $this->provider === 'Instagram' ) {
                        // Generate a placeholder email using the Instagram identifier
                        $user_profile->email = 'instagram_' . $user_profile->identifier . '@instagram-login.local';
                    } else {
                        // Generic placeholder for other providers
                        $user_profile->email = strtolower( $this->provider ) . '_' . $user_profile->identifier . '@social-login.local';
                    }
                } else {
                    wp_redirect( $this->account_page_url );
                    exit;
                }
            }

            $wp_user = get_user_by( 'email', $user_profile->email );

            if ( ! $wp_user ) {
                $this->register_new_user( $user_profile );
            } else {
                $this->login_user( $wp_user );
            }
        } catch ( \Hybridauth\Exception\HttpClientFailureException $e ) {
            // Handle HTTP/curl errors
            wp_die( __( 'Network connection failed. Please try again later.', 'wpuf-pro' ) . '<br><br>Debug: ' . esc_html( $e->getMessage() ) );
        } catch ( \Hybridauth\Exception\HttpRequestFailedException $e ) {
            // Handle API request errors
            $error_message = $e->getMessage();

            // Check for LinkedIn scope/permission errors
            if ( strpos( $error_message, 'unauthorized_scope_error' ) !== false ||
                 strpos( $error_message, 'Not enough permissions' ) !== false ||
                 strpos( $error_message, 'ACCESS_DENIED' ) !== false ||
                 strpos( $error_message, 'linkedin' ) !== false ||
                 strpos( $error_message, 'me.GET.NO_VERSION' ) !== false ) {
                wp_die( __( 'LinkedIn authentication failed due to permission/scope configuration.', 'wpuf-pro' ) . '<br><br>' .
                       __( 'Steps to fix this:', 'wpuf-pro' ) . '<br>' .
                       '1. Go to your <a href="https://www.linkedin.com/developer/apps" target="_blank">LinkedIn Developer Console</a><br>' .
                       '2. Select your app and go to the "Products" tab<br>' .
                       '3. Ensure "Sign In with LinkedIn using OpenID Connect" product is added and approved<br>' .
                       '4. In the Auth tab, make sure your redirect URLs are correctly configured<br>' .
                       '5. Verify these scopes are available: openid, profile, email<br>' .
                       '6. Try waiting 10-15 minutes after making changes as LinkedIn may need time to propagate<br><br>' .
                       __( 'Note: LinkedIn has strict approval processes and some products may take time to become active.', 'wpuf-pro' ) . '<br><br>' .
                       'Debug: ' . esc_html( $error_message ) );
            }

            // Check for Twitter credentials
            if ( strpos( $error_message, 'twitter' ) !== false || strpos( $error_message, 'Twitter' ) !== false ) {
                wp_die( __( 'Twitter authentication failed. Please check your Twitter API settings.', 'wpuf-pro' ) . '<br><br>Debug: ' . esc_html( $error_message ) . '<br><br>This usually means your Twitter API credentials are for v2 (Client ID/Secret) but this plugin requires v1.1 credentials (Consumer Key/Secret). Please check the Twitter Developer Portal and use API v1.1 credentials.' );
            }

            // Generic API request error
            wp_die( __( 'Authentication failed. Please check your social provider settings.', 'wpuf-pro' ) . '<br><br>Debug: ' . esc_html( $error_message ) );
        } catch ( \Hybridauth\Exception\InvalidArgumentException $e ) {
            // Handle configuration errors
            wp_die( __( 'Social login configuration error. Please contact administrator.', 'wpuf-pro' ) . '<br><br>Debug: ' . esc_html( $e->getMessage() ) );
        } catch ( TypeError $e ) {
            // Handle PHP type errors (like null being passed where string expected)

            // Check for specific Facebook access token type errors
            if ( strpos( $e->getMessage(), 'getKidFromOLDCToken' ) !== false ||
                 strpos( $e->getMessage(), 'must be of type string, null given' ) !== false ) {
                wp_die( __( 'Facebook authentication failed: Invalid access token format.', 'wpuf-pro' ) . '<br><br>' .
                       __( 'This usually indicates an issue with the Facebook OAuth process. Please try the following:', 'wpuf-pro' ) . '<br>' .
                       '1. Clear your browser cache and cookies<br>' .
                       '2. Verify your Facebook App ID and Secret are correct<br>' .
                       '3. Make sure your Facebook App is in "Live" mode (not Development)<br>' .
                       '4. Check that your redirect URL is properly configured in Facebook App settings<br>' .
                       '5. Try the authentication process again<br><br>' .
                       'Debug: ' . esc_html( $e->getMessage() ) );
            }

            // Generic type error
            wp_die( __( 'Social login failed due to data type mismatch.', 'wpuf-pro' ) . '<br><br>Debug: ' . esc_html( $e->getMessage() ) );
        } catch ( Exception $e ) {
            // Fallback for any other exceptions
            wp_die( __( 'Social login failed. Please try again.', 'wpuf-pro' ) . '<br><br>Debug: ' . esc_html( $e->getMessage() ) );
        }
    }

    /**
     * Check if current license is Professional or equivalent
     *
     * @since 4.1.7
     *
     * @return bool|WP_Error
     */
    private function is_professional_license() {
        // Check if WP User Frontend Pro is available and has license
        if ( ! class_exists( 'WP_User_Frontend_Pro' ) ) {

            return false;
        }

        // Try to get the license from the Pro plugin
        try {
            // Method 1: Check through WPUF Pro license option
            $license_data = get_option( 'wpuf_license', null );
            if ( is_array( $license_data ) && isset( $license_data['title'] ) ) {
                $title = strtolower( trim( $license_data['title'] ) );

                // Check for Professional license or equivalent (AppSumo lifetime, Business, etc.)
                $professional_licenses = [
                    'professional',
                    'wpuf-pro-ltd-appsumo',
                    'business',
                    'enterprise',
                    'lifetime',
                    'pro'
                ];

                foreach ( $professional_licenses as $valid_license ) {
                    if ( $title === $valid_license || strpos( $title, $valid_license ) !== false ) {
                        return true;
                    }
                }
            }

            // Method 2: Check through Appsero license system
            $license_option = get_option( 'appsero_' . md5( 'wpuf-pro' ) . '_manage_license', null );
            if ( is_array( $license_option ) && isset( $license_option['title'] ) ) {
                $title = strtolower( trim( $license_option['title'] ) );

                $professional_licenses = [
                    'professional',
                    'wpuf-pro-ltd-appsumo',
                    'business',
                    'enterprise',
                    'lifetime',
                    'pro'
                ];

                foreach ( $professional_licenses as $valid_license ) {
                    if ( $title === $valid_license || strpos( $title, $valid_license ) !== false ) {
                        return true;
                    }
                }
            }

            // Method 3: Check if wpuf_pro function exists and try to access license
            if ( function_exists( 'wpuf_pro' ) ) {
                $wpuf_pro = wpuf_pro();

                // Check if Update class and license property exists
                if ( isset( $wpuf_pro->admin ) && property_exists( $wpuf_pro->admin, 'update' ) ) {
                    $update = $wpuf_pro->admin->update;
                    if ( property_exists( $update, 'license' ) && method_exists( $update->license, 'get_license' ) ) {
                        $license = $update->license->get_license();
                        if ( is_array( $license ) && isset( $license['title'] ) ) {
                            $title = strtolower( trim( $license['title'] ) );

                            $professional_licenses = [
                                'professional',
                                'wpuf-pro-ltd-appsumo',
                                'business',
                                'enterprise',
                                'lifetime',
                                'pro'
                            ];

                            foreach ( $professional_licenses as $valid_license ) {
                                if ( $title === $valid_license || strpos( $title, $valid_license ) !== false ) {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }

        } catch ( Exception $e ) {
            return new WP_Error( 'error_checking_professional_license', __( 'Error checking professional license: ', 'wpuf-pro' ) . esc_html( $e->getMessage() ) );
        }

        // Default to false if we can't determine the license type
        return false;
    }

    /**
     * Filter admin menu settings section
     *
     * @param array $settings
     *
     * @return array
     */
    public function wpuf_social_settings_tab( $settings ) {
        $s_settings = array(
            array(
                'id'    => 'wpuf_social_api',
                'title' => __( 'Social Login', 'wpuf-pro' ),
                'icon'  => 'dashicons-share',
            ),
        );

        return array_merge( $settings, $s_settings );
    }

    /**
     * Render settings fields for admin settings section
     *
     * @param array $settings_fields
     *
     * @return array
     **/

    public function wpuf_pro_social_api_fields( $settings_fields ) {
        $social_settings_fields = array(
            'wpuf_social_api' => array(
                'enabled'              => array(
                    'name'  => 'enabled',
                    'label' => __( 'Enable Social Login', 'wpuf-pro' ),
                    'type'  => 'checkbox',
                    'desc'  => __( 'Enabling this will add Social Icons under registration form to allow users to login or register using Social Profiles', 'wpuf-pro' ),
                ),
                'facebook_app_label'   => array(
                    'name'  => 'fb_app_label',
                    'label' => __( 'Facebook App Settings', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => '<a target="_blank" href="https://developers.facebook.com/apps/">' . __( 'Create an App', 'wpuf-pro' ) . '</a> ' . __( 'if you don\'t have one and fill App ID and App Secret below.', 'wpuf-pro' ),
                ),
                'facebook_app_url'     => array(
                    'name'  => 'fb_app_url',
                    'label' => __( 'Redirect URI', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => "<input class='regular-text' type='text' disabled value='{$this->account_page_url}'>",
                ),
                'facebook_app_id'      => array(
                    'name'  => 'fb_app_id',
                    'label' => __( 'App Id', 'wpuf-pro' ),
                    'type'  => 'text',
                ),
                'facebook_app_secret'  => array(
                    'name'  => 'fb_app_secret',
                    'label' => __( 'App Secret', 'wpuf-pro' ),
                    'type'  => 'text',
                ),
                'twitter_app_label'    => array(
                    'name'  => 'twitter_app_label',
                    'label' => __( 'Twitter App Settings', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => '<a target="_blank" href="https://apps.twitter.com/">' . __( 'Create an App', 'wpuf-pro' ) . '</a> ' . __( 'if you don\'t have one and fill Consumer key and Consumer Secret below.', 'wpuf-pro' ),
                ),
                'twitter_app_url'      => array(
                    'name'  => 'twitter_app_url',
                    'label' => __( 'Callback URL', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => "<input class='regular-text' type='text' disabled value='{$this->account_page_url}'>",
                ),
                'twitter_app_id'       => array(
                    'name'  => 'twitter_app_id',
                    'label' => __( 'Consumer Key', 'wpuf-pro' ),
                    'type'  => 'text',
                ),
                'twitter_app_secret'   => array(
                    'name'  => 'twitter_app_secret',
                    'label' => __( 'Consumer Secret', 'wpuf-pro' ),
                    'type'  => 'text',
                ),
                'google_app_label'     => array(
                    'name'  => 'google_app_label',
                    'label' => __( 'Google App Settings', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => '<a target="_blank" href="https://console.developers.google.com/project">' . __( 'Create an App', 'wpuf-pro' ) . '</a> ' . __( 'if you don\'t have one and fill Client ID and Client Secret below.', 'wpuf-pro' ),
                ),
                'google_app_url'       => array(
                    'name'  => 'google_app_url',
                    'label' => __( 'Redirect URI', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => "<input class='regular-text' type='text' disabled value='{$this->account_page_url}'>",
                ),
                'google_app_id'        => array(
                    'name'  => 'google_app_id',
                    'label' => __( 'Client ID', 'wpuf-pro' ),
                    'type'  => 'text',
                ),
                'google_app_secret'    => array(
                    'name'  => 'google_app_secret',
                    'label' => __( 'Client secret', 'wpuf-pro' ),
                    'type'  => 'text',
                ),
                'linkedin_app_label'   => array(
                    'name'  => 'linkedin_app_label',
                    'label' => __( 'Linkedin App Settings', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => '<a target="_blank" href="https://www.linkedin.com/developer/apps">' . __( 'Create an App', 'wpuf-pro' ) . '</a>' . __( ' if you don\'t have one. <strong>Important:</strong> You must add the "Sign In with LinkedIn using OpenID Connect" product to your app and get it approved.', 'wpuf-pro' ),
                ),
                'linkedin_app_url'     => array(
                    'name'  => 'linkedin_app_url',
                    'label' => __( 'Redirect URL', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => "<input class='regular-text' type='text' disabled value='{$this->account_page_url}'>",
                ),
                'linkedin_app_id'      => array(
                    'name'  => 'linkedin_app_id',
                    'label' => __( 'Client ID', 'wpuf-pro' ),
                    'type'  => 'text',
                ),
                'linkedin_app_secret'  => array(
                    'name'  => 'linkedin_app_secret',
                    'label' => __( 'Client Secret', 'wpuf-pro' ),
                    'type'  => 'text',
                ),
                /*
                'instagram_app_label'  => array(
                    'name'  => 'instagram_app_label',
                    'label' => __( 'Instagram Business Login Settings', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => '<div style="background: #e7f3ff; border: 1px solid #bee5eb; padding: 15px; border-radius: 4px; margin: 10px 0;"><strong>📱 Instagram Business Login</strong><br><br>' .
                               __( 'Instagram login is available for <strong>Business and Professional Instagram accounts only</strong>. Personal Instagram accounts cannot use social login.', 'wpuf-pro' ) . '<br><br><strong>' .
                               __( 'Setup Instructions:', 'wpuf-pro' ) . '</strong><br>' .
                               '1. Go to <a href="https://developers.facebook.com/" target="_blank">Facebook Developer Console</a><br>' .
                               '2. Create or select your Facebook App<br>' .
                               '3. Add <strong>Instagram Business Login</strong> product to your app<br>' .
                               '4. In App Settings > Basic, copy your <strong>App ID</strong> and <strong>App Secret</strong><br>' .
                               '5. In Instagram Business Login settings, add your redirect URI<br>' .
                               '6. Submit your app for review if needed<br>' .
                               '7. Users must have Instagram Business/Professional accounts linked to a Facebook Page<br><br>' .
                               '<strong>⚠️ Important:</strong> Instagram Basic Display API is deprecated. Use Instagram Business Login only. Personal accounts will see an error.</div>',
                ),
                'instagram_app_url'    => array(
                    'name'  => 'instagram_app_url',
                    'label' => __( 'Redirect URI', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => "<input class='regular-text' type='text' disabled value='{$this->account_page_url}'>",
                ),
                'instagram_app_id'     => array(
                    'name'  => 'instagram_app_id',
                    'label' => __( 'App ID', 'wpuf-pro' ),
                    'type'  => 'text',
                    'desc'  => __( 'Use your main Facebook App ID (from Settings > Basic)', 'wpuf-pro' ),
                ),
                'instagram_app_secret' => array(
                    'name'  => 'instagram_app_secret',
                    'label' => __( 'App Secret', 'wpuf-pro' ),
                    'type'  => 'text',
                    'desc'  => __( 'Use your main Facebook App Secret (from Settings > Basic)', 'wpuf-pro' ),
                ),
                */

                // Only show GitHub settings for Professional license users
                'github_app_label'     => array(
                    'name'  => 'github_app_label',
                    'label' => __( 'GitHub App Settings (Professional License Required)', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => __( 'GitHub login requires a Professional license. Available for Professional, Business, Enterprise, or AppSumo lifetime license users. Please create a GitHub OAuth App and enter your credentials below.', 'wpuf-pro' ),
                ),
                'github_app_url'       => array(
                    'name'  => 'github_app_url',
                    'label' => __( 'Authorization Callback URL', 'wpuf-pro' ),
                    'type'  => 'html',
                    'desc'  => "<input class='regular-text' type='text' disabled value='{$this->account_page_url}'>",
                ),
                'github_app_id'        => array(
                    'name'  => 'github_app_id',
                    'label' => __( 'Client ID', 'wpuf-pro' ),
                    'type'  => 'text',
                    'desc'  => ! $this->is_professional_license() ? '<span style="color: #dc3545; font-weight: bold;">' . __( 'Professional/Business/Enterprise license required to use GitHub login', 'wpuf-pro' ) . '</span>' : '',
                    'disabled' => ! $this->is_professional_license(),
                ),
                'github_app_secret'    => array(
                    'name'  => 'github_app_secret',
                    'label' => __( 'Client Secret', 'wpuf-pro' ),
                    'type'  => 'text',
                    'desc'  => ! $this->is_professional_license() ? '<span style="color: #dc3545; font-weight: bold;">' . __( 'Professional/Business/Enterprise license required to use GitHub login', 'wpuf-pro' ) . '</span>' : '',
                    'disabled' => ! $this->is_professional_license(),
                ),
            ),
        );

        // Only show GitHub settings for Professional license users
        if ( ! $this->is_professional_license() ) {
            unset( $social_settings_fields['wpuf_social_api']['github_app_label'] );
            unset( $social_settings_fields['wpuf_social_api']['github_app_url'] );
            unset( $social_settings_fields['wpuf_social_api']['github_app_id'] );
            unset( $social_settings_fields['wpuf_social_api']['github_app_secret'] );
        }
        return array_merge( $settings_fields, $social_settings_fields );
    }

    /**
     * Render social login icons
     *
     * @return void
     */
    public function render_social_logins() {
        $is_enabled = wpuf_get_option( 'enabled', 'wpuf_social_api', 'off' );

        if ( ! wpuf_validate_boolean( $is_enabled ) ) {
            return;
        }

        $configured_providers = [];

        //facebook config from admin
        $fb_id     = wpuf_get_option( 'fb_app_id', 'wpuf_social_api' );
        $fb_secret = wpuf_get_option( 'fb_app_secret', 'wpuf_social_api' );

        if ( $fb_id !== '' && $fb_secret !== '' ) {
            $configured_providers [] = 'facebook';
        }
        //google config from admin
        $g_id     = wpuf_get_option( 'google_app_id', 'wpuf_social_api' );
        $g_secret = wpuf_get_option( 'google_app_secret', 'wpuf_social_api' );

        if ( $g_id !== '' && $g_secret !== '' ) {
            $configured_providers [] = 'google';
        }
        //linkedin config from admin
        $l_id     = wpuf_get_option( 'linkedin_app_id', 'wpuf_social_api' );
        $l_secret = wpuf_get_option( 'linkedin_app_secret', 'wpuf_social_api' );

        if ( $l_id !== '' && $l_secret !== '' ) {
            $configured_providers [] = 'linkedin';
        }

        //Twitter config from admin
        $twitter_id     = wpuf_get_option( 'twitter_app_id', 'wpuf_social_api' );
        $twitter_secret = wpuf_get_option( 'twitter_app_secret', 'wpuf_social_api' );

        if ( $twitter_id !== '' && $twitter_secret !== '' ) {
            $configured_providers [] = 'twitter';
        }

        //Instagram config from admin - BUSINESS ACCOUNTS ONLY (COMMENTED OUT)
        // Instagram login works with Business/Professional accounts only
        // $instagram_id     = wpuf_get_option( 'instagram_app_id', 'wpuf_social_api' );
        // $instagram_secret = wpuf_get_option( 'instagram_app_secret', 'wpuf_social_api' );

        // if ( $instagram_id !== '' && $instagram_secret !== '' ) {
        //     $configured_providers [] = 'instagram';
        // }

        //GitHub config from admin - PROFESSIONAL LICENSE ONLY
        $github_id     = wpuf_get_option( 'github_app_id', 'wpuf_social_api' );
        $github_secret = wpuf_get_option( 'github_app_secret', 'wpuf_social_api' );

        if ( $github_id !== '' && $github_secret !== '' && $this->is_professional_license() ) {
            $configured_providers [] = 'github';
        }

        /**
         * Filter the list of Providers connect links to display
         *
         * @param array $providers
         *
         * @since 1.0.0
         */
        $providers = apply_filters( 'wpuf_social_provider_list', $configured_providers );

        $redirect_uri = preg_replace( '/^http:/i', 'https:', $this->account_page_url );

        $base_url  = $this->account_page_url;
        $pro       = true;

        if ( empty( $this->account_page_url ) ) {
            ?>
                <div class="error">
                    <p><?php esc_html_e( 'Account Page URL is not set in WPUF Admin Settings.', 'wpuf-pro' ); ?></p>
                </div>
            <?php
            return;
        }

        if ( ! is_user_logged_in() && ! empty( $configured_providers ) ) {
            $this->render_modern_social_login( $providers );
        }
    }

    /**
     * Render modern social login interface
     *
     * @param array $providers
     * @return void
     */
    private function render_modern_social_login( $providers ) {
        ?>
        <script>
            var wpuf_reg_form_id = document.querySelector('input[name=form_id]')?.value || '';
            if (wpuf_reg_form_id) {
                document.cookie = 'wpuf_reg_form_id' + "=" + wpuf_reg_form_id + ';path=/';
            }
            window.addEventListener('DOMContentLoaded', (e) => {
                document.querySelectorAll('.wpuf-social-signin-btn').forEach(function(link){
                    if (wpuf_reg_form_id && link.href.indexOf('form_id=') === -1) {
                        link.href = link.href + '&form_id=' + wpuf_reg_form_id;
                    }
                });
            });
        </script>

        <div class="wpuf-modern-social-container">
            <!-- Separator -->
            <div class="wpuf-social-separator">
                <?php _e( 'or continue with', 'wpuf-pro' ); ?>
            </div>

            <!-- Individual Sign-in Buttons -->
            <div class="wpuf-social-signin-buttons">
                <?php foreach ( $providers as $provider ) :
                    $provider_name = $this->get_provider_display_name( $provider );
                    ?>
                    <a href="<?php echo esc_url( add_query_arg( array( 'wpuf_reg' => $provider ), $this->account_page_url ) ); ?>"
                       class="wpuf-social-signin-btn <?php echo esc_attr( $provider ); ?>">
                        <img src="<?php echo esc_url( $this->get_provider_icon_url( $provider ) ); ?>"
                             alt="<?php echo esc_attr( $provider_name ); ?>" />
                        <?php printf( esc_html__( 'Sign in with %s', 'wpuf-pro' ), $provider_name ); ?>
                    </a>
                <?php endforeach; ?>
            </div>
        </div>
        <?php
    }

    /**
     * Get display name for social provider
     *
     * @param string $provider
     * @return string
     */
    private function get_provider_display_name( $provider ) {
        $provider_names = array(
            'facebook' => 'Facebook',
            'google' => 'Google',
            'linkedin' => 'LinkedIn',
            'twitter' => 'Twitter',
            'github' => 'GitHub',
            'instagram' => 'Instagram'
        );

        return isset( $provider_names[ $provider ] ) ? $provider_names[ $provider ] : ucfirst( $provider );
    }

    /**
     * Get icon URL for social provider
     *
     * @param string $provider
     * @return string
     */
    private function get_provider_icon_url( $provider ) {
        // Use modern SVG icons for better quality and scalability
        $modern_icon_path = WPUF_PRO_ASSET_URI . '/images/social-icons/modern/' . $provider . '.svg';
        $original_icon_path = WPUF_PRO_ASSET_URI . '/images/social-icons/' . $provider . '.png';

        // Check if modern SVG icon exists, otherwise fallback to PNG
        $modern_file_path = dirname( dirname( dirname( __FILE__ ) ) ) . '/assets/images/social-icons/modern/' . $provider . '.svg';

        if ( file_exists( $modern_file_path ) ) {
            return $modern_icon_path;
        }

        return $original_icon_path;
    }

    /**
     * Custom LinkedIn OpenID Connect authentication
     *
     * @param Hybridauth $hybridauth
     * @return mixed
     */
    private function authenticate_linkedin_openid( $hybridauth ) {
        try {

            // First try the standard authentication
            $adapter = $hybridauth->authenticate( 'LinkedIn' );

            // Override the getUserProfile method to use OpenID Connect userinfo endpoint
            $access_token = $adapter->getAccessToken();
            if ( is_array( $access_token ) ) {
                $token = $access_token['access_token'];
            } else {
                $token = $access_token;
            }

            // Make a direct call to LinkedIn's OpenID Connect userinfo endpoint
            $response = wp_remote_get( 'https://api.linkedin.com/v2/userinfo', array(
                'headers' => array(
                    'Authorization' => 'Bearer ' . $token,
                    'Accept' => 'application/json'
                ),
                'timeout' => 30
            ) );

            if ( is_wp_error( $response ) ) {
                throw new Exception( 'Failed to fetch user info from LinkedIn: ' . $response->get_error_message() );
            }

            $response_code = wp_remote_retrieve_response_code( $response );
            $user_data = json_decode( wp_remote_retrieve_body( $response ), true );

            if ( $response_code !== 200 || empty( $user_data ) ) {
                throw new Exception( 'Invalid response from LinkedIn userinfo endpoint. Response code: ' . $response_code );
            }

            // Create a mock user profile object compatible with HybridAuth
            $user_profile = new stdClass();
            $user_profile->identifier = $user_data['sub'] ?? '';
            $user_profile->email = $user_data['email'] ?? '';
            $user_profile->firstName = $user_data['given_name'] ?? '';
            $user_profile->lastName = $user_data['family_name'] ?? '';
            $user_profile->displayName = $user_data['name'] ?? ($user_profile->firstName . ' ' . $user_profile->lastName);
            $user_profile->photoURL = $user_data['picture'] ?? '';

            // Override the adapter's getUserProfile method
            $adapter->userProfile = $user_profile;

            return $adapter;

        } catch ( Exception $e ) {
            // Fall back to standard authentication
            throw $e; // Re-throw to let the main error handler deal with it
        }
    }

    /**
     * Convert camelCase to snake_case
     *
     * @param string $input
     * @return string
     */
    private function camel_to_snake_case( $input ) {
        return strtolower( preg_replace( '/(?<!^)[A-Z]/', '_$0', $input ) );
    }

    /**
     * Recursive function to generate a unique username.
     *
     * If the username already exists, will add a numerical suffix which will increase until a unique username is found.
     *
     * @param string $username
     *
     * @return string The unique username.
     */
    public function generate_unique_username( $username ) {
        static $i;
        if ( null === $i ) {
            $i = 1;
        } else {
            $i ++;
        }
        $username = preg_replace( '/([^@]*).*/', '$1', $username );
        if ( ! username_exists( $username ) ) {
            return $username;
        }
        $new_username = sprintf( '%s_%s', $username, $i );
        if ( ! username_exists( $new_username ) ) {
            return $new_username;
        } else {
            return call_user_func( array( $this, 'generate_unique_username' ), $username );
        }
    }

    /**
     * Register a new user
     *
     * @param object $data
     *
     * @param string $provider
     *
     * @return void
     */
    private function register_new_user( $data ) {
        $form_settings = array();
        $form_id       = $this->form_id;
        $form_settings = wpuf_get_form_settings( $form_id );

        if ( wpuf_is_vendor_reg( $form_id ) ) {
            $this->account_page_url = wpuf_get_dokan_redirect_url();
        }

        $user_role = isset( $form_settings['role'] ) ? $form_settings['role'] : 'subscriber';
        $uname     = $data->email;

        if ( empty( $uname ) ) {
            $uname = $data->displayName;
        }

        // For Twitter users without email, try to use displayName or identifier
        if ( empty( $uname ) && ! empty( $data->identifier ) ) {
            $uname = 'x' .'_user_' . $data->identifier;
        }

        // Fallback if still no username
        if ( empty( $uname ) ) {
            $uname = 'social_user_' . time();
        }

        $userdata = array(
            'user_login' => $uname ? $uname : $this->generate_unique_username( $uname ),
            'user_email' => $data->email,
            'user_pass'  => wp_generate_password(),
            'first_name' => $data->firstName,
            'last_name'  => $data->lastName,
            'role'       => $user_role,
        );

        $user_id = wp_insert_user( $userdata );
        if ( ! is_wp_error( $user_id ) ) {
            $this->store_avatar( $user_id, $data );
            $this->login_user( get_userdata( $user_id ) );
            wp_redirect( $this->account_page_url );
            exit;
        }
    }

    /**
     * Log in existing users
     *
     * @param WP_User $wp_user
     *
     * return void
     */
    private function login_user( $wp_user ) {
        clean_user_cache( $wp_user->ID );
        wp_clear_auth_cookie();
        wp_set_current_user( $wp_user->ID );
        wp_set_auth_cookie( $wp_user->ID, true, false );
        update_user_caches( $wp_user );
    }

    /**
     * Store user avatar from facebook
     *
     * @since 3.4.7
     *
     * @param $user_id
     * @param $data
     *
     * @return void
     */
    private function store_avatar( $user_id, $data ) {
        if ( is_null( $this->access_token ) || $this->provider !== 'facebook' ) {
            return;
        }

        $image_url     = $data->photoURL . '&access_token=' . $this->access_token;
        $profile_image = file_get_contents( $image_url );
        $headers       = [];

        array_map(
            function ( $key_value ) use ( &$headers ) {
                $arr_split           = preg_split( '/:/', $key_value, 2 );
                $headers[ $arr_split[0] ] = $arr_split && ! empty( $arr_split[1] ) ? $arr_split[1] : '';
            }, $http_response_header
        );

        $file_name      = pathinfo( $headers['Location'], PATHINFO_FILENAME );
        $file_extension = explode( '/', $headers['Content-Type'] )[1];
        $hash           = wp_hash( time() );
        $hash           = substr( $hash, 0, 8 );

        $file_name = $data->identifier . '-' . $hash . '.' . $file_extension;
        $file_path = wp_upload_dir()['path'] . '/' . $file_name;

        file_put_contents( $file_path, $profile_image );

        $attachment = [
            'post_author'    => $user_id,
            'post_mime_type' => $headers['Content-Type'],
            'post_title'     => $file_name,
            'post_content'   => '',
            'post_status'    => 'inherit',
            'comment_status' => 'closed',
        ];

        $attach_id    = wp_insert_attachment( $attachment, $file_path );
        $imagenew     = get_post( $attach_id );
        $fullsizepath = get_attached_file( $imagenew->ID );

        if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
            require_once ABSPATH . 'wp-admin/includes/image.php';
        }

        $attach_data = wp_generate_attachment_metadata( $attach_id, $fullsizepath );
        wp_update_attachment_metadata( $attach_id, $attach_data );
        update_user_meta( $user_id, 'user_avatar', $attach_id );
    }
}

$wpuf_social_login = WPUF_Social_Login::init();
