<?php

/**
 * Plugin Name: OnesID SSO Authentication
 * Description: OnesID CIBA authentication for WordPress.
 * Version: 0.2.1
 * Author: Franz Geffke
 * License: Not for redistribution
 * Text Domain: ones-auth
 * Requires PHP: 7.2.5
 * Requires at least: 6.0
 * 
 * This program is copyrighted by Franz Geffke (Softmax Co., Ltd.)
 */

require __DIR__ . '/vendor/autoload.php';
use ones\oidc\OnesOidc;

class Ones_Auth_Plugin {
	// TODO: Update
	const DEFAULT_DEVICE_CONFIG_PATH = '/etc/px-device-identity/device.yml';
	const DEFAULT_DEVICE_PRIVATE_KEY_PATH = '/root/.local/share/px-device-identity/private.pem';
	const DEFAULT_RESOURCE_URL = 'https://your-server.com';
	const DEFAULT_ENABLE_CONSENT_FLOW = true;
	const DEFAULT_CONSENT_REASON = "Consent to share information";

	const DEFAULT_CONSENT_CONTENT_FIRST_NAME = true;
	const DEFAULT_CONSENT_CONTENT_LAST_NAME = true;
	const DEFAULT_CONSENT_CONTENT_FULL_NAME = true;
	const DEFAULT_CONSENT_CONTENT_LOCALIZED_FIRST_NAME = true;
	const DEFAULT_CONSENT_CONTENT_LOCALIZED_LAST_NAME = true;
	const DEFAULT_CONSENT_CONTENT_LOCALIZED_FULL_NAME = true;
	const DEFAULT_CONSENT_CONTENT_IDENTITY_DOCUMENT_NUMBER = true;
	const DEFAULT_CONSENT_CONTENT_IDENTITY_DOCUMENT_ISSUE_DATE = true;
	const DEFAULT_CONSENT_CONTENT_IDENTITY_DOCUMENT_EXPIRY_DATE = true;
	const DEFAULT_CONSENT_CONTENT_DATE_OF_BIRTH = true;
	const DEFAULT_CONSENT_CONTENT_EMAIL = true;
	const DEFAULT_CONSENT_CONTENT_PHONE_NUMBER = true;

/**
* Initializes the plugin.
*
* To keep the initialization fast, only add filter and action
* hooks in the constructor.
*/

    public function __construct() {
        add_shortcode( 'ones-login-form', array( $this, 'render_login_form' ) );
		add_shortcode( 'ones-account-info', array( $this, 'render_account_info' ) );
		add_action( 'wp_logout', array( $this, 'redirect_after_logout' ) );
        add_action( 'login_form_login', array( $this, 'redirect_to_custom_login' ) );
        add_filter( 'authenticate', array( $this, 'maybe_redirect_at_authenticate' ), 101, 3 );
		add_filter( 'login_redirect', array( $this, 'redirect_after_login' ), 10, 3 );

		add_action('admin_menu', array($this, 'register_settings_page'));
    	add_action('admin_init', array($this, 'register_settings'));
	}

    /**
    * Plugin activation hook.
    * Creates all WordPress pages needed by the plugin.
    */
    public static function plugin_activated() {
        // Information needed for creating the plugin's pages
        $page_definitions = array(
            'member-login' => array(
                'title' => __( 'OnesID Sign In', 'ones-auth' ),
                'content' => '[ones-login-form]'
            ),

            'member-account' => array(
                'title' => __( 'OnesID Account', 'ones-auth' ),
                'content' => '[ones-account-info]'
            ),
        );

        foreach ( $page_definitions as $slug => $page ) {
            // Check that the page doesn't exist already
            $query = new WP_Query( 'pagename=' . $slug );
            if ( ! $query->have_posts() ) {
                // Add the page using the data from the array above
                wp_insert_post(
                    array(
                        'post_content'   => $page['content'],
                        'post_name'      => $slug,
                        'post_title'     => $page['title'],
                        'post_status'    => 'publish',
                        'post_type'      => 'page',
                        'ping_status'    => 'closed',
                        'comment_status' => 'closed',
                    )
                );
            }
        }
    }

	/**
	 * A shortcode for rendering the login form.
	 *
	 * @param  array   $attributes  Shortcode attributes.
	 * @param  string  $content     The text content for shortcode. Not used.
	 *
	 * @return string  The shortcode output
	 */
	public function render_login_form( $attributes, $content = null ) {
		// Parse shortcode attributes
		$default_attributes = array( 'show_title' => false );
		$attributes = shortcode_atts( $default_attributes, $attributes );

		if ( is_user_logged_in() ) {
			return __( 'You are already signed in.', 'ones-auth' );
		}

		// Pass the redirect parameter to the WordPress login functionality: by default,
		// don't specify a redirect, but if a valid redirect URL has been passed as
		// request parameter, use it.
		$attributes['redirect'] = '';
		if ( isset( $_REQUEST['redirect_to'] ) ) {
			$attributes['redirect'] = wp_validate_redirect( $_REQUEST['redirect_to'], $attributes['redirect'] );
		}

		// Error messages
		$errors = array();
		if ( isset( $_REQUEST['login'] ) ) {
			$error_codes = explode( ',', $_REQUEST['login'] );

			foreach ( $error_codes as $code ) {
				$errors []= $this->get_error_message( $code );
			}
		}
		$attributes['errors'] = $errors;

		// Check if user just logged out
		$attributes['logged_out'] = isset( $_REQUEST['logged_out'] ) && $_REQUEST['logged_out'] == true;

		// Render the login form using an external template
		return $this->get_template_html( 'login_form', $attributes );
	}

	public function render_account_info( $attributes, $content = null ) {
		// Parse shortcode attributes
		$default_attributes = array( 'show_title' => true );
		$attributes = shortcode_atts( $default_attributes, $attributes );
	
		if ( ! is_user_logged_in() ) {
			return __( 'You need to be signed in to view your account.', 'ones-auth' );
		}
	
		// Get current user info
		$current_user = wp_get_current_user();
		$user_id = $current_user->ID;
	
		$attributes['user_id'] = $user_id;
		$attributes['username'] = $current_user->user_login;
		$attributes['email'] = $current_user->user_email;
		$attributes['first_name'] = $current_user->first_name;
		$attributes['last_name'] = $current_user->last_name;
		
		// Get additional user meta
		$attributes['domain'] = get_user_meta($user_id, 'domain', true);
		$attributes['sub'] = get_user_meta($user_id, 'sub', true);
		$attributes['username_without_domain'] = get_user_meta($user_id, 'username_without_domain', true);
		$attributes['localized_first_name'] = get_user_meta($user_id, 'localized_first_name', true);
		$attributes['localized_last_name'] = get_user_meta($user_id, 'localized_last_name', true);
		$attributes['date_of_birth'] = get_user_meta($user_id, 'date_of_birth', true);
		$attributes['phone_number'] = get_user_meta($user_id, 'phone_number', true);
		$attributes['identity_document_number'] = get_user_meta($user_id, 'identity_document_number', true);
		$attributes['identity_document_issue_date'] = get_user_meta($user_id, 'identity_document_issue_date', true);
		$attributes['identity_document_expiry_date'] = get_user_meta($user_id, 'identity_document_expiry_date', true);
	
		// Check if there are any messages to display
		$attributes['messages'] = array();
		if ( isset( $_GET['account_updated'] ) ) {
			$attributes['messages'][] = __( 'Your account has been updated successfully.', 'ones-auth' );
		}
		
		// Render the account info template
		return $this->get_template_html( 'account_info', $attributes );
	}
	

    /**
	 * Renders the contents of the given template to a string and returns it.
	 *
	 * @param string $template_name The name of the template to render (without .php)
	 * @param array  $attributes    The PHP variables for the template
	 *
	 * @return string               The contents of the template.
	 */
	private function get_template_html( $template_name, $attributes = null ) {
		if ( ! $attributes ) {
			$attributes = array();
		}

		ob_start();

		do_action( 'ones_auth_before_' . $template_name );

		require( 'templates/' . $template_name . '.php');

		do_action( 'ones_auth_after_' . $template_name );

		$html = ob_get_contents();
		ob_end_clean();

		return $html;
	}

	/**
	 * Redirect the user to the custom login page instead of wp-login.php.
     * 
     * This function is called
     * - user enters login page
     * - submits the login form
     * 
     * TODO: Maybe hook-in the CIBA process here?
	 */
	public function redirect_to_custom_login() {
		$redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : null;

		if ( $_SERVER['REQUEST_METHOD'] == 'GET' ) {
			if ( is_user_logged_in() ) {
				$this->redirect_logged_in_user( $redirect_to );
				exit;
			}

			// The rest are redirected to the login page
			$login_url = get_permalink( get_page_by_path('member-login')->ID );
			if ( ! empty( $redirect_to ) ) {
				$login_url = add_query_arg( 'redirect_to', $redirect_to, $login_url );
			}

			wp_redirect( $login_url );
			exit;
		}
	}

	/**
	 * Redirects the user to the correct page depending on whether he / she
	 * is an admin or not.
	 *
	 * @param string $redirect_to   An optional redirect_to URL for admin users
	 */
	private function redirect_logged_in_user( $redirect_to = null ) {
		$user = wp_get_current_user();
		if ( user_can( $user, 'manage_options' ) ) {
			if ( $redirect_to ) {
				wp_safe_redirect( $redirect_to );
			} else {
				wp_redirect( admin_url() );
			}
		} else {
			wp_redirect( get_permalink( get_page_by_path('member-account')->ID ) );
		}
	}

	/**
	 * Returns the URL to which the user should be redirected after the (successful) login.
	 *
	 * @param string           $redirect_to           The redirect destination URL.
	 * @param string           $requested_redirect_to The requested redirect destination URL passed as a parameter.
	 * @param WP_User|WP_Error $user                  WP_User object if login was successful, WP_Error object otherwise.
	 *
	 * @return string Redirect URL
	 */
	public function redirect_after_login( $redirect_to, $requested_redirect_to, $user ) {
		$redirect_url = home_url();

		if ( ! isset( $user->ID ) ) {
			return $redirect_url;
		}

		if ( user_can( $user, 'manage_options' ) ) {
			// Use the redirect_to parameter if one is set, otherwise redirect to admin dashboard.
			if ( $requested_redirect_to == '' ) {
				$redirect_url = admin_url();
			} else {
				$redirect_url = $redirect_to;
			}
		} else {
			// Non-admin users always go to their account page after login
			$redirect_url = get_permalink( get_page_by_path('member-account')->ID );
		}

		return wp_validate_redirect( $redirect_url, home_url() );
	}

	/**
	 * Redirect to custom login page after the user has been logged out.
	 */
	public function redirect_after_logout() {
		$redirect_url = add_query_arg( 'logged_out', 'true', get_permalink( get_page_by_path('member-login')->ID ) );
		wp_safe_redirect( $redirect_url );
		exit;
	}

	/**
	 * Updates user meta with information from the user info array.
	 * 
	 * @param int $user_id  The user ID.
	 * @param array{
	 * 		domain: string,
	 * 		sub: string,
	 * 		username: string,
	 * 		username_without_domain: string,
	 * 		first_name: string,
	 * 		last_name: string,
	 * 		localized_first_name: string,
	 * 		localized_last_name: string,
	 * 		identity_document_number: string,
	 * 		identity_document_issue_date: string,
	 * 		identity_document_expiry_date: string,
	 * 		date_of_birth: string,
	 * 		email: string,
	 * 		phone_number: string
	 * }
	 */
	public function update_user_from_user_info($user_id, $user_info) {

		if (isset($user_info) && is_array($user_info)) {
			// Loop through user_info and update user meta, skipping first_name and last_name
			foreach ($user_info as $key => $value) {
				// echo $key . ' => ' . $value . '<br>';
				if ($key !== 'first_name' && $key !== 'last_name') {
					update_user_meta($user_id, $key, $value);
				}
			}
			// wp_die(json_encode($user_info));
	
			// Prepare data for updating WordPress core fields
			$wp_user_data = [
				'ID' => $user_id,
				'first_name' => $user_info['firstName'] ?? '',
				'last_name' => $user_info['lastName'] ?? '',
				'display_name' => trim(($user_info['firstName'] ?? '') . ' ' . ($user_info['lastName'] ?? ''))
			];
	
			// Get current first_name and last_name from user meta
			$current_first_name = get_user_meta($user_id, 'first_name', true);
			$current_last_name = get_user_meta($user_id, 'last_name', true);
	
			// Update first_name if it's not already set
			if ($current_first_name === '') {
				$wp_user_data['first_name'] = $user_info['firstName'] ?? '';
			}
	
			// Update last_name if it's not already set
			if ($current_last_name === '') {
				$wp_user_data['last_name'] = $user_info['lastName'] ?? '';
			}
	
			// Update user in WordPress if either first_name or last_name was not set
			if ($current_first_name === '' || $current_last_name === '') {
				wp_update_user($wp_user_data);
			}
		}
	}

	/**
	 * Redirect the user after authentication if there were any errors.
	 *
	 * @param Wp_User|Wp_Error  $user       The signed in user, or the errors that have occurred during login.
	 * @param string            $username   The user name used to log in.
	 * @param string            $password   The password used to log in.
	 *
	 * @return Wp_User|Wp_Error The logged in user, or error information if there were errors.
	 */
	public function maybe_redirect_at_authenticate($user, $username, $password) {
		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
			$login_type = isset($_POST['login_type']) ? $_POST['login_type'] : 'custom';
	
			if ($login_type === 'default') {
				// Use default WordPress authentication
				return $user;
			} else {
				// Use custom authentication
				if (empty($username)) {
					$user = new WP_Error('empty_username', $this->get_error_message('empty_username'));
				} else {
					// Start output buffering to prevent any output
					ob_start();


					$oidc = new OnesOidc();

					// LOAD DEVICE INFO
					$device_config_path = get_option('ones_auth_device_config_path', self::DEFAULT_DEVICE_CONFIG_PATH);
					$device_private_key_path = get_option('ones_auth_device_private_key_path', self::DEFAULT_DEVICE_PRIVATE_KEY_PATH);
					$deviceProps = $oidc->get_device_properties(
						$device_config_path,         // Update path as needed
						$device_private_key_path     // Update path as needed
					);
					$openidInfo = $oidc->get_openid_info($deviceProps['host']);
					$resource_url = get_option('ones_auth_resource_url', self::DEFAULT_RESOURCE_URL);

					try {

						$api_response = $oidc->user_ciba_auth(
							$username,
							$deviceProps['clientId'],
							$deviceProps['privateKey'],
							$openidInfo['providerMetadata'],
							$openidInfo['providerJwks'],
							$resource_url,
							"Please authorize this request",
							"openid profile"
						);
					
						// Clear the output buffer
						ob_end_clean();
		
						$user_info  = $api_response['id_token_content'];
						
						// If the API response is valid, check if the user exists
						$user = get_user_by('login', $username);  // Assuming username is actually an email
						if (!$user) {
							$consent_flow_enabled = get_option('ones_auth_enable_consent_flow', self::DEFAULT_ENABLE_CONSENT_FLOW);
							if (!$consent_flow_enabled) {
								// CONSENT FLOW DISABLED
								// NEW USER
								// If the user doesn't exist in WordPress, and consent flow is disabled, create a new user
								$user_id = wp_create_user($username, wp_generate_password(), $username);
								if (is_wp_error($user_id)) {
									// Handle user creation error
									error_log("Failed to create user: " . $user_id->get_error_message());
									$user = new WP_Error('creation_failed', __('Failed to create user account.', 'personalize-login'));
								} else {
									$user = get_user_by('ID', $user_id);
									// Set additional user meta
									update_user_meta($user_id, 'source', 'api_registration');
									$user->set_role('subscriber');  // Or whatever default role you want
					
									// Save additional user info
									$this->update_user_from_user_info($user_id, $user_info);
								}
							} else {
								// CONSENT FLOW ENABLED
								// NEW USER
								// If the user doesn't exist in wordpress, and consent flow is enabled, engage consent flow and then create a user
								$consentSettings = [
									'ones_auth_consent_content_first_name' => get_option('ones_auth_consent_content_first_name', self::DEFAULT_CONSENT_CONTENT_FIRST_NAME),
									'ones_auth_consent_content_last_name' => get_option('ones_auth_consent_content_last_name', self::DEFAULT_CONSENT_CONTENT_LAST_NAME),
									'ones_auth_consent_content_full_name' => get_option('ones_auth_consent_content_full_name', self::DEFAULT_CONSENT_CONTENT_FULL_NAME),
									'ones_auth_consent_content_date_of_birth' => get_option('ones_auth_consent_content_date_of_birth', self::DEFAULT_CONSENT_CONTENT_DATE_OF_BIRTH),
									'ones_auth_consent_content_localized_first_name' => get_option('ones_auth_consent_content_localized_first_name', self::DEFAULT_CONSENT_CONTENT_LOCALIZED_FIRST_NAME),
									'ones_auth_consent_content_localized_last_name' => get_option('ones_auth_consent_content_localized_last_name', self::DEFAULT_CONSENT_CONTENT_LOCALIZED_LAST_NAME),
									'ones_auth_consent_content_localized_full_name' => get_option('ones_auth_consent_content_localized_full_name', self::DEFAULT_CONSENT_CONTENT_LOCALIZED_FULL_NAME),
									'ones_auth_consent_content_identity_document_number' => get_option('ones_auth_consent_content_identity_document_number', self::DEFAULT_CONSENT_CONTENT_IDENTITY_DOCUMENT_NUMBER),
									'ones_auth_consent_content_identity_document_issue_date' => get_option('ones_auth_consent_content_identity_document_issue_date', self::DEFAULT_CONSENT_CONTENT_IDENTITY_DOCUMENT_ISSUE_DATE),
									'ones_auth_consent_content_identity_document_expiry_date' => get_option('ones_auth_consent_content_identity_document_expiry_date', self::DEFAULT_CONSENT_CONTENT_IDENTITY_DOCUMENT_EXPIRY_DATE),
									'ones_auth_consent_content_email' => get_option('ones_auth_consent_content_email', self::DEFAULT_CONSENT_CONTENT_EMAIL),
									'ones_auth_consent_content_phone_number' => get_option('ones_auth_consent_content_phone_number', self::DEFAULT_CONSENT_CONTENT_PHONE_NUMBER),
								];

								$consent_response = $oidc->user_consent_flow(
									$user_info['sub'],
									$deviceProps['clientId'],
									$deviceProps['privateKey'],
									$openidInfo['providerMetadata'],
									$resource_url,
									$deviceProps['host'],
									$consentSettings,
									get_option('ones_auth_consent_reason', self::DEFAULT_CONSENT_REASON)
								);

								if ($consent_response['status'] === 'approved') {
									$user_id = wp_create_user($username, wp_generate_password(), $username);
									if (is_wp_error($user_id)) {
										// Handle user creation error
										error_log("Failed to create user: " . $user_id->get_error_message());
										$user = new WP_Error('creation_failed', __('Failed to create user account.', 'personalize-login'));
									} else {
										$user = get_user_by('ID', $user_id);
										// Set additional user meta
										update_user_meta($user_id, 'source', 'api_registration');
										$user->set_role('subscriber');  // Or whatever default role you want
						
										// Save additional user info
										$this->update_user_from_user_info($user_id, $consent_response['content']);
									}
								}
							}
						} else {
							// User exists, update their information
							$user_id = $user->ID;
							$this->update_user_from_user_info($user_id, $user_info);
						}
					} catch (Exception $e) {
						// If an error occurred during the API request, return an error
						// $user = new WP_Error('api_error', $this->get_error_message('api_error'));
						$user = new WP_Error('invalid_username', $this->get_error_message('invalid_username'));
					}
				}
			}
	
			if (is_wp_error($user)) {
				$error_codes = join(',', $user->get_error_codes());
				$login_url = get_permalink( get_page_by_path('member-login')->ID );
				$login_url = add_query_arg('login', $error_codes, $login_url);
				wp_redirect($login_url);
				exit;
			}
		}
	
		return $user;
	}

	/**
	 * Finds and returns a matching error message for the given error code.
	 *
	 * @param string $error_code    The error code to look up.
	 *
	 * @return string               An error message.
	 */
	private function get_error_message( $error_code ) {
		switch ( $error_code ) {
			// Login errors

			case 'empty_username':
				return __( 'You do have a OnesID, right?', 'ones-auth' );

			case 'empty_password':
				return __( 'You need to enter a password to login.', 'ones-auth' );

			case 'invalid_username':
				return __(
					"We don't have any users with that OnesID address. Maybe you used a different one when signing up?",
					'ones-auth'
				);

			case 'incorrect_password':
				$err = __(
					"The password you entered wasn't quite right. <a href='%s'>Did you forget your password</a>?",
					'ones-auth'
				);
				return sprintf( $err, wp_lostpassword_url() );

			default:
				break;
		}

		return __( 'An unknown error occurred. Please try again later.', 'ones-auth' );
	}

	// SETTINGS

	/**
	 * Registers the settings page for the plugin.
	 */
	public function register_settings_page() {
		add_options_page(
			'OnesID SSO Settings',
			'OnesID SSO',
			'manage_options',
			'ones-auth-settings',
			array($this, 'render_settings_page')
		);
	}

	public function render_settings_page() {
		?>
		<div class="wrap">
			<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
			<form action="options.php" method="post">
				<?php
				settings_fields('ones_auth_options');
				do_settings_sections('ones-auth-settings');
				submit_button('Save Settings');
				?>
			</form>
		</div>
		<?php
	}

	/**
	 * Registers the settings for the plugin.
	 * 
	 * - Device config path
	 * - Device private key path
	 * - Resource URL
	 */
	public function register_settings() {
		register_setting(
			'ones_auth_options',
			'ones_auth_device_config_path',
			array(
				'default' => self::DEFAULT_DEVICE_CONFIG_PATH,
				'sanitize_callback' => 'sanitize_text_field',
			)
		);

		register_setting(
			'ones_auth_options',
			'ones_auth_device_private_key_path',
			array(
				'default' => self::DEFAULT_DEVICE_PRIVATE_KEY_PATH,
				'sanitize_callback' => 'sanitize_text_field',
			)
		);

		register_setting(
			'ones_auth_options',
			'ones_auth_resource_url',
			array(
				'default' => self::DEFAULT_RESOURCE_URL,
				'sanitize_callback' => 'sanitize_text_field',
			)
		);

		register_setting(
			'ones_auth_options',
			'ones_auth_enable_consent_flow',
			array(
				'default' => self::DEFAULT_ENABLE_CONSENT_FLOW,
				'sanitize_callback' => 'sanitize_text_field',
			)
		);
		

		register_setting(
			'ones_auth_options',
			'ones_auth_consent_content_first_name',
			array(
				'default' => self::DEFAULT_CONSENT_CONTENT_FIRST_NAME,
				'sanitize_callback' => 'sanitize_text_field',
			)
		);
	
		add_settings_section(
			'ones_auth_main_section',
			'Main Settings',
			array($this, 'main_section_callback'),
			'ones-auth-settings'
		);
	
		add_settings_section(
			'ones_auth_consent_content_section',
			'Consent Settings',
			array($this, 'consent_content_section_callback'),
			'ones-auth-settings'
		);
	
		add_settings_field(
			'ones_auth_device_config_path',
			'Device Config Path',
			array($this, 'device_config_path_callback'),
			'ones-auth-settings',
			'ones_auth_main_section'
		);

		add_settings_field(
			'ones_auth_device_private_key_path',
			'Device Private Key Path',
			array($this, 'device_private_key_path_callback'),
			'ones-auth-settings',
			'ones_auth_main_section'
		);

		add_settings_field(
			'ones_auth_resource_url',
			'Resource URL',
			array($this, 'resource_url_callback'),
			'ones-auth-settings',
			'ones_auth_main_section'
		);

		add_settings_field(
			'ones_auth_enable_consent_flow',
			'Enable CONSENT flow',
			array($this, 'enable_consent_flow_callback'),
			'ones-auth-settings',
			'ones_auth_main_section'
		);

		// Consent Reason
		register_setting(
			'ones_auth_options',
			'ones_auth_consent_reason',
			array(
				'default' => self::DEFAULT_CONSENT_REASON,
				'sanitize_callback' => 'sanitize_text_field',
			)
		);

		add_settings_field(
			'ones_auth_consent_reason',
			'Consent Reason',
			array($this, 'consent_reason_callback'),
			'ones-auth-settings',
			'ones_auth_consent_content_section'
		);

		// First Name
        register_setting(
            'ones_auth_options',
            'ones_auth_consent_content_first_name',
            array(
                'default' => self::DEFAULT_CONSENT_CONTENT_FIRST_NAME,
                'sanitize_callback' => 'rest_sanitize_boolean',
            )
        );

        add_settings_field(
            'ones_auth_consent_content_first_name',
            'First name (required)',
            array($this, 'enable_consent_content_first_name'),
            'ones-auth-settings',
            'ones_auth_consent_content_section'
        );

        // Last Name
        register_setting(
            'ones_auth_options',
            'ones_auth_consent_content_last_name',
            array(
                'default' => self::DEFAULT_CONSENT_CONTENT_LAST_NAME,
                'sanitize_callback' => 'rest_sanitize_boolean',
            )
        );

        add_settings_field(
            'ones_auth_consent_content_last_name',
            'Last name (required)',
            array($this, 'enable_consent_content_last_name'),
            'ones-auth-settings',
            'ones_auth_consent_content_section'
        );

		// Full Name
		register_setting(
			'ones_auth_options',
			'ones_auth_consent_content_full_name',
			array(
				'default' => self::DEFAULT_CONSENT_CONTENT_FULL_NAME,
				'sanitize_callback' => 'rest_sanitize_boolean',
			)
		);

		// add_settings_field(
		// 	'ones_auth_consent_content_full_name',
		// 	'Full Name',
		// 	array($this, 'enable_consent_content_full_name'),
		// 	'ones-auth-settings',
		// 	'ones_auth_consent_content_section'
		// );

        // Localized First Name
        register_setting(
            'ones_auth_options',
            'ones_auth_consent_content_localized_first_name',
            array(
                'default' => self::DEFAULT_CONSENT_CONTENT_LOCALIZED_FIRST_NAME,
                'sanitize_callback' => 'rest_sanitize_boolean',
            )
        );

        add_settings_field(
            'ones_auth_consent_content_localized_first_name',
            'Localized First Name',
            array($this, 'enable_consent_content_localized_first_name'),
            'ones-auth-settings',
            'ones_auth_consent_content_section'
        );

        // Localized Last Name
        register_setting(
            'ones_auth_options',
            'ones_auth_consent_content_localized_last_name',
            array(
                'default' => self::DEFAULT_CONSENT_CONTENT_LOCALIZED_LAST_NAME,
                'sanitize_callback' => 'rest_sanitize_boolean',
            )
        );

        add_settings_field(
            'ones_auth_consent_content_localized_last_name',
            'Localized Last Name',
            array($this, 'enable_consent_content_localized_last_name'),
            'ones-auth-settings',
            'ones_auth_consent_content_section'
        );

		// Localized Full Name
		register_setting(
			'ones_auth_options',
			'ones_auth_consent_content_localized_full_name',
			array(
				'default' => self::DEFAULT_CONSENT_CONTENT_LOCALIZED_FULL_NAME,
				'sanitize_callback' => 'rest_sanitize_boolean',
			)
		);

		// add_settings_field(
		// 	'ones_auth_consent_content_localized_full_name',
		// 	'Localized Full Name',
		// 	array($this, 'enable_consent_content_localized_full_name'),
		// 	'ones-auth-settings',
		// 	'ones_auth_consent_content_section'
		// );

        // Identity Document Number
        register_setting(
            'ones_auth_options',
            'ones_auth_consent_content_identity_document_number',
            array(
                'default' => self::DEFAULT_CONSENT_CONTENT_IDENTITY_DOCUMENT_NUMBER,
                'sanitize_callback' => 'rest_sanitize_boolean',
            )
        );

        add_settings_field(
            'ones_auth_consent_content_identity_document_number',
            'National ID No.',
            array($this, 'enable_consent_content_identity_document_number'),
            'ones-auth-settings',
            'ones_auth_consent_content_section'
        );

		// Identity Document Issue Date
		register_setting(
			'ones_auth_options',
			'ones_auth_consent_content_identity_document_issue_date',
			array(
				'default' => self::DEFAULT_CONSENT_CONTENT_IDENTITY_DOCUMENT_ISSUE_DATE,
				'sanitize_callback' => 'rest_sanitize_boolean',
			)
		);

		add_settings_field(
			'ones_auth_consent_content_identity_document_issue_date',
			'National ID Issue Date',
			array($this, 'enable_consent_content_identity_document_issue_date'),
			'ones-auth-settings',
			'ones_auth_consent_content_section'
		);

		// Identity Document Expiry Date
		register_setting(
			'ones_auth_options',
			'ones_auth_consent_content_identity_document_expiry_date',
			array(
				'default' => self::DEFAULT_CONSENT_CONTENT_IDENTITY_DOCUMENT_EXPIRY_DATE,
				'sanitize_callback' => 'rest_sanitize_boolean',
			)
		);

		add_settings_field(
			'ones_auth_consent_content_identity_document_expiry_date',
			'National ID Expiry Date',
			array($this, 'enable_consent_content_identity_document_expiry_date'),
			'ones-auth-settings',
			'ones_auth_consent_content_section'
		);

        // Date of Birth
        register_setting(
            'ones_auth_options',
            'ones_auth_consent_content_date_of_birth',
            array(
                'default' => self::DEFAULT_CONSENT_CONTENT_DATE_OF_BIRTH,
                'sanitize_callback' => 'rest_sanitize_boolean',
            )
        );

        add_settings_field(
            'ones_auth_consent_content_date_of_birth',
            'Date of Birth',
            array($this, 'enable_consent_content_date_of_birth'),
            'ones-auth-settings',
            'ones_auth_consent_content_section'
        );

        // Email
        register_setting(
            'ones_auth_options',
            'ones_auth_consent_content_email',
            array(
                'default' => self::DEFAULT_CONSENT_CONTENT_EMAIL,
                'sanitize_callback' => 'rest_sanitize_boolean',
            )
        );

        add_settings_field(
            'ones_auth_consent_content_email',
            'Email',
            array($this, 'enable_consent_content_email'),
            'ones-auth-settings',
            'ones_auth_consent_content_section'
        );

        // Phone Number
        register_setting(
            'ones_auth_options',
            'ones_auth_consent_content_phone_number',
            array(
                'default' => self::DEFAULT_CONSENT_CONTENT_PHONE_NUMBER,
                'sanitize_callback' => 'rest_sanitize_boolean',
            )
        );

        add_settings_field(
            'ones_auth_consent_content_phone_number',
            'Phone Number',
            array($this, 'enable_consent_content_phone_number'),
            'ones-auth-settings',
            'ones_auth_consent_content_section'
        );
	}

	public function main_section_callback() {
		echo '<p>' . __('These are the main settings for the OnesID SSO Authentication plugin.<br/>To proceed, please ensure your server has already been registered with px-device-identity.<br/>Developed by Franz Geffke for Softmax Co., Ltd.', 'ones-auth') . '</p>';
		echo '<p>' . __('For more information, please refer to the <a href="https://bitbucket.org/softmax-auth/workspace/snippets/Lz4KqL" target="_blank">OnesID documentation</a>.', 'ones-auth') . '</p>';
	}

	public function consent_content_section_callback() {
		echo '<p>' . __('These are properties to be requested as part of the consent flow.<br/>All properties are optional.', 'ones-auth') . '</p>';
	}
	
	public function device_config_path_callback() {
		$device_config_path = get_option('ones_auth_device_config_path', self::DEFAULT_DEVICE_CONFIG_PATH);
		echo '<input type="text" name="ones_auth_device_config_path" value="' . esc_attr($device_config_path) . '" class="regular-text">';
		echo '<p class="description">' . __('Enter the full path to your device configuration file.', 'ones-auth') . '</p>';
	}
	
	public function device_private_key_path_callback() {
		$device_private_key_path = get_option('ones_auth_device_private_key_path', self::DEFAULT_DEVICE_PRIVATE_KEY_PATH);
		echo '<input type="text" name="ones_auth_device_private_key_path" value="' . esc_attr($device_private_key_path) . '" class="regular-text">';
		echo '<p class="description">' . __('Enter the full path to your device private key file.', 'ones-auth') . '</p>';
	}

	public function resource_url_callback() {
		$resource_url = get_option('ones_auth_resource_url', self::DEFAULT_RESOURCE_URL);
		echo '<input type="text" name="ones_auth_resource_url" value="' . esc_attr($resource_url) . '" class="regular-text">';
		echo '<p class="description">' . __('Enter the public URL which this device is registered as.', 'ones-auth') . '</p>';
	}

	public function enable_consent_flow_callback() {
		$enable_consent_flow = get_option('ones_auth_enable_consent_flow', self::DEFAULT_ENABLE_CONSENT_FLOW);
		echo '<label for="ones_auth_enable_consent_flow">';
		echo '<input type="checkbox" id="ones_auth_enable_consent_flow" name="ones_auth_enable_consent_flow" value="1" ' . checked(1, $enable_consent_flow, false) . '>';
		echo ' ' . __('Enable consent flow for user sign-up.', 'ones-auth');
		echo '</label>';
		echo '<p class="description">' . __('Confirm user registration with consent request on OnesID.', 'ones-auth') . '</p>';
	}

	public function consent_reason_callback() {
		$consent_reason = get_option('ones_auth_consent_reason', self::DEFAULT_CONSENT_REASON);
		echo '<input type="text" name="ones_auth_consent_reason" value="' . esc_attr($consent_reason) . '" class="regular-text">';
		echo '<p class="description">' . __('Enter the reason for requesting consent.', 'ones-auth') . '</p>';
	}

	public function enable_consent_content_first_name() {
        $this->render_consent_field('first_name', true);
    }

    public function enable_consent_content_last_name() {
        $this->render_consent_field('last_name', true);
    }

	public function enable_consent_content_full_name() {
		$this->render_consent_field('full_name');
	}

    public function enable_consent_content_localized_first_name() {
        $this->render_consent_field('localized_first_name');
    }

    public function enable_consent_content_localized_last_name() {
        $this->render_consent_field('localized_last_name');
    }

	public function enable_consent_content_localized_full_name() {
		$this->render_consent_field('localized_full_name');
	}

    public function enable_consent_content_identity_document_number() {
        $this->render_consent_field('identity_document_number');
    }

	public function enable_consent_content_identity_document_issue_date() {
		$this->render_consent_field('identity_document_issue_date');
	}

	public function enable_consent_content_identity_document_expiry_date() {
		$this->render_consent_field('identity_document_expiry_date');
	}

    public function enable_consent_content_date_of_birth() {
        $this->render_consent_field('date_of_birth');
    }


    public function enable_consent_content_email() {
        $this->render_consent_field('email');
    }

    public function enable_consent_content_phone_number() {
        $this->render_consent_field('phone_number');
    }

    private function render_consent_field($field, $disabled = false) {
		$option_name = "ones_auth_consent_content_{$field}";
		$constant_name = "DEFAULT_CONSENT_CONTENT_" . strtoupper($field);
		$value = get_option($option_name, constant("self::{$constant_name}"));
	
		echo '<label for="' . esc_attr($option_name) . '">';
		echo '<input type="checkbox" id="' . esc_attr($option_name) . '" name="' . esc_attr($option_name) . '" value="1" ' . checked(1, $value, false) . ($disabled ? ' checked disabled' : '') . '>';
		echo '</label>';
	}

}

// Initialize the plugin
$ones_auth_pages_plugin = new Ones_Auth_Plugin();

// Create custom pages
register_activation_hook( __FILE__, array( 'Ones_Auth_Plugin', 'plugin_activated' ) );