<?php
/**
 * Descomplicar® Crescimento Digital
 * https://descomplicar.pt
 */

/**
 * Authentication Endpoints
 *
 * Handles all authentication-related REST API endpoints
 *
 * @package Care_API
 * @subpackage Endpoints
 * @version    1.0.0
 * @author     Descomplicar® <dev@descomplicar.pt>
 * @link       https://descomplicar.pt
 * @since      1.0.0
 */

namespace Care_API\Endpoints;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Class Auth_Endpoints
 *
 * REST API endpoints for authentication operations
 *
 * @since 1.0.0
 */
class Auth_Endpoints {

    /**
     * API namespace
     *
     * @var string
     */
    const API_NAMESPACE = 'care/v1';

    /**
     * Register all authentication routes
     *
     * @since 1.0.0
     */
    public static function register_routes() {
        // Login endpoint
        register_rest_route( self::API_NAMESPACE, '/auth/login', array(
            array(
                'methods'             => 'POST',
                'callback'            => array( self::class, 'login' ),
                'permission_callback' => array( self::class, 'check_rate_limit' ),
                'args'                => array(
                    'username' => array(
                        'required'          => true,
                        'type'              => 'string',
                        'sanitize_callback' => 'sanitize_user',
                        'validate_callback' => array( self::class, 'validate_username' ),
                        'description'       => 'Username or email address'
                    ),
                    'password' => array(
                        'required'          => true,
                        'type'              => 'string',
                        'sanitize_callback' => 'sanitize_text_field',
                        'validate_callback' => array( self::class, 'validate_password' ),
                        'description'       => 'User password'
                    ),
                    'remember_me' => array(
                        'required'          => false,
                        'type'              => 'boolean',
                        'default'           => false,
                        'description'       => 'Remember login for extended period'
                    )
                ),
            ),
        ));

        // Logout endpoint
        register_rest_route( self::API_NAMESPACE, '/auth/logout', array(
            array(
                'methods'             => 'POST',
                'callback'            => array( self::class, 'logout' ),
                'permission_callback' => array( self::class, 'check_authentication' ),
            ),
        ));

        // Refresh token endpoint
        register_rest_route( self::API_NAMESPACE, '/auth/refresh', array(
            array(
                'methods'             => 'POST',
                'callback'            => array( self::class, 'refresh_token' ),
                'permission_callback' => array( self::class, 'check_authentication' ),
            ),
        ));

        // Validate token endpoint
        register_rest_route( self::API_NAMESPACE, '/auth/validate', array(
            array(
                'methods'             => 'GET',
                'callback'            => array( self::class, 'validate_token' ),
                'permission_callback' => array( self::class, 'check_authentication' ),
            ),
        ));

        // User profile endpoint
        register_rest_route( self::API_NAMESPACE, '/auth/profile', array(
            array(
                'methods'             => 'GET',
                'callback'            => array( self::class, 'get_user_profile' ),
                'permission_callback' => array( self::class, 'check_authentication' ),
            ),
            array(
                'methods'             => 'PUT',
                'callback'            => array( self::class, 'update_user_profile' ),
                'permission_callback' => array( self::class, 'check_authentication' ),
                'args'                => array(
                    'first_name' => array(
                        'required'          => false,
                        'type'              => 'string',
                        'sanitize_callback' => 'sanitize_text_field',
                        'description'       => 'User first name'
                    ),
                    'last_name' => array(
                        'required'          => false,
                        'type'              => 'string',
                        'sanitize_callback' => 'sanitize_text_field',
                        'description'       => 'User last name'
                    ),
                    'email' => array(
                        'required'          => false,
                        'type'              => 'string',
                        'sanitize_callback' => 'sanitize_email',
                        'validate_callback' => 'is_email',
                        'description'       => 'User email address'
                    ),
                ),
            ),
        ));

        // Password reset request - WITH RATE LIMITING
        register_rest_route( self::API_NAMESPACE, '/auth/forgot-password', array(
            array(
                'methods'             => 'POST',
                'callback'            => array( self::class, 'forgot_password' ),
                'permission_callback' => array( self::class, 'check_rate_limit' ),
                'args'                => array(
                    'username' => array(
                        'required'          => true,
                        'type'              => 'string',
                        'sanitize_callback' => 'sanitize_user',
                        'description'       => 'Username or email address'
                    ),
                ),
            ),
        ));

        // Password reset - WITH RATE LIMITING
        register_rest_route( self::API_NAMESPACE, '/auth/reset-password', array(
            array(
                'methods'             => 'POST',
                'callback'            => array( self::class, 'reset_password' ),
                'permission_callback' => array( self::class, 'check_rate_limit' ),
                'args'                => array(
                    'key' => array(
                        'required'          => true,
                        'type'              => 'string',
                        'sanitize_callback' => 'sanitize_text_field',
                        'description'       => 'Password reset key'
                    ),
                    'login' => array(
                        'required'          => true,
                        'type'              => 'string',
                        'sanitize_callback' => 'sanitize_user',
                        'description'       => 'User login'
                    ),
                    'password' => array(
                        'required'          => true,
                        'type'              => 'string',
                        'sanitize_callback' => 'sanitize_text_field',
                        'validate_callback' => array( self::class, 'validate_password' ),
                        'description'       => 'New password'
                    ),
                ),
            ),
        ));
    }

    /**
     * Handle user login
     *
     * @param \WP_REST_Request $request The request object.
     * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure.
     * @since 1.0.0
     */
    public static function login( $request ) {
        try {
            $username = $request->get_param( 'username' );
            $password = $request->get_param( 'password' );
            $remember_me = $request->get_param( 'remember_me' );

            // Input validation
            if ( empty( $username ) || empty( $password ) ) {
                return new \WP_Error(
                    'missing_credentials',
                    'Username and password are required',
                    array( 'status' => 400 )
                );
            }

            // Try to authenticate user
            $user = wp_authenticate( $username, $password );

            if ( is_wp_error( $user ) ) {
                return new \WP_Error(
                    'authentication_failed',
                    'Invalid username or password',
                    array( 'status' => 401 )
                );
            }

            // Check if user has permission to access API
            if ( ! self::user_can_access_api( $user ) ) {
                return new \WP_Error(
                    'insufficient_permissions',
                    'User does not have permission to access this API',
                    array( 'status' => 403 )
                );
            }

            // Check if user account is active/not suspended
            if ( ! self::is_user_active( $user ) ) {
                return new \WP_Error(
                    'account_suspended',
                    'Your account has been suspended. Please contact support.',
                    array( 'status' => 403 )
                );
            }

            // Generate JWT token
            if ( ! class_exists( 'Care_API\\Services\\JWT_Service' ) ) {
                return new \WP_Error(
                    'service_unavailable',
                    'Authentication service is not available',
                    array( 'status' => 503 )
                );
            }

            $token_data = \Care_API\Services\JWT_Service::generate_token( $user->ID, $remember_me );

            if ( is_wp_error( $token_data ) ) {
                return $token_data;
            }

            // Log successful login
            if ( class_exists( 'Care_API\\Utils\\API_Logger' ) ) {
                \Care_API\Utils\API_Logger::log_info( 
                    'User login successful',
                    array(
                        'user_id' => $user->ID,
                        'username' => $user->user_login,
                        'ip_address' => self::get_client_ip(),
                        'user_agent' => sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] ?? '' )
                    )
                );
            }

            // Create session record
            if ( class_exists( 'Care_API\\Services\\Session_Service' ) ) {
                \Care_API\Services\Session_Service::create_session(
                    $user->ID,
                    $token_data['token'],
                    $token_data['expires_at']
                );
            }

            // Prepare response data
            $response_data = array(
                'success' => true,
                'message' => 'Login successful',
                'data' => array(
                    'token' => $token_data['token'],
                    'token_expires' => $token_data['expires_at'],
                    'refresh_token' => $token_data['refresh_token'] ?? null,
                    'user' => array(
                        'id' => $user->ID,
                        'username' => $user->user_login,
                        'email' => $user->user_email,
                        'first_name' => $user->first_name,
                        'last_name' => $user->last_name,
                        'display_name' => $user->display_name,
                        'roles' => $user->roles,
                        'capabilities' => self::get_user_api_capabilities( $user ),
                    ),
                ),
            );

            return new \WP_REST_Response( $response_data, 200 );

        } catch ( Exception $e ) {
            if ( class_exists( 'Care_API\\Utils\\Error_Handler' ) ) {
                \Care_API\Utils\Error_Handler::handle_exception( $e );
            }

            return new \WP_Error(
                'login_error',
                'An error occurred during login process',
                array( 'status' => 500 )
            );
        }
    }

    /**
     * Handle user logout
     *
     * @param \WP_REST_Request $request The request object.
     * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure.
     * @since 1.0.0
     */
    public static function logout( $request ) {
        try {
            $current_user_id = get_current_user_id();

            if ( ! $current_user_id ) {
                return new \WP_Error(
                    'not_authenticated',
                    'User is not authenticated',
                    array( 'status' => 401 )
                );
            }

            // Get token from header
            $token = self::get_token_from_request( $request );

            if ( $token ) {
                // Invalidate JWT token
                if ( class_exists( 'Care_API\\Services\\JWT_Service' ) ) {
                    \Care_API\Services\JWT_Service::invalidate_token( $token );
                }

                // Remove session record
                if ( class_exists( 'Care_API\\Services\\Session_Service' ) ) {
                    \Care_API\Services\Session_Service::destroy_session( $current_user_id, $token );
                }
            }

            // Log successful logout
            if ( class_exists( 'Care_API\\Utils\\API_Logger' ) ) {
                \Care_API\Utils\API_Logger::log_info(
                    'User logout successful',
                    array(
                        'user_id' => $current_user_id,
                        'ip_address' => self::get_client_ip()
                    )
                );
            }

            return new \WP_REST_Response(
                array(
                    'success' => true,
                    'message' => 'Logout successful'
                ),
                200
            );

        } catch ( Exception $e ) {
            if ( class_exists( 'Care_API\\Utils\\Error_Handler' ) ) {
                \Care_API\Utils\Error_Handler::handle_exception( $e );
            }

            return new \WP_Error(
                'logout_error',
                'An error occurred during logout process',
                array( 'status' => 500 )
            );
        }
    }

    /**
     * Refresh JWT token
     *
     * @param \WP_REST_Request $request The request object.
     * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure.
     * @since 1.0.0
     */
    public static function refresh_token( $request ) {
        try {
            $current_user_id = get_current_user_id();

            if ( ! $current_user_id ) {
                return new \WP_Error(
                    'not_authenticated',
                    'User is not authenticated',
                    array( 'status' => 401 )
                );
            }

            $current_token = self::get_token_from_request( $request );

            if ( ! $current_token ) {
                return new \WP_Error(
                    'no_token',
                    'No authentication token provided',
                    array( 'status' => 400 )
                );
            }

            // Generate new token
            if ( ! class_exists( 'Care_API\\Services\\JWT_Service' ) ) {
                return new \WP_Error(
                    'service_unavailable',
                    'Authentication service is not available',
                    array( 'status' => 503 )
                );
            }

            $token_data = \Care_API\Services\JWT_Service::refresh_token( $current_token );

            if ( is_wp_error( $token_data ) ) {
                return $token_data;
            }

            // Update session record
            if ( class_exists( 'Care_API\\Services\\Session_Service' ) ) {
                \Care_API\Services\Session_Service::update_session(
                    $current_user_id,
                    $current_token,
                    $token_data['token'],
                    $token_data['expires_at']
                );
            }

            $response_data = array(
                'success' => true,
                'message' => 'Token refreshed successfully',
                'data' => array(
                    'token' => $token_data['token'],
                    'token_expires' => $token_data['expires_at'],
                    'refresh_token' => $token_data['refresh_token'] ?? null,
                ),
            );

            return new \WP_REST_Response( $response_data, 200 );

        } catch ( Exception $e ) {
            if ( class_exists( 'Care_API\\Utils\\Error_Handler' ) ) {
                \Care_API\Utils\Error_Handler::handle_exception( $e );
            }

            return new \WP_Error(
                'token_refresh_error',
                'An error occurred while refreshing token',
                array( 'status' => 500 )
            );
        }
    }

    /**
     * Validate current token
     *
     * @param \WP_REST_Request $request The request object.
     * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure.
     * @since 1.0.0
     */
    public static function validate_token( $request ) {
        try {
            $current_user_id = get_current_user_id();

            if ( ! $current_user_id ) {
                return new \WP_Error(
                    'token_invalid',
                    'Token is invalid or expired',
                    array( 'status' => 401 )
                );
            }

            $token = self::get_token_from_request( $request );

            if ( ! $token ) {
                return new \WP_Error(
                    'no_token',
                    'No authentication token provided',
                    array( 'status' => 400 )
                );
            }

            // Validate token
            if ( class_exists( 'Care_API\\Services\\JWT_Service' ) ) {
                $token_valid = \Care_API\Services\JWT_Service::validate_token( $token );

                if ( is_wp_error( $token_valid ) ) {
                    return $token_valid;
                }
            }

            $user = get_userdata( $current_user_id );

            $response_data = array(
                'success' => true,
                'message' => 'Token is valid',
                'data' => array(
                    'valid' => true,
                    'user_id' => $current_user_id,
                    'username' => $user->user_login,
                    'roles' => $user->roles,
                    'capabilities' => self::get_user_api_capabilities( $user ),
                    'token_expires' => self::get_token_expiry( $token ),
                ),
            );

            return new \WP_REST_Response( $response_data, 200 );

        } catch ( Exception $e ) {
            if ( class_exists( 'Care_API\\Utils\\Error_Handler' ) ) {
                \Care_API\Utils\Error_Handler::handle_exception( $e );
            }

            return new \WP_Error(
                'token_validation_error',
                'An error occurred while validating token',
                array( 'status' => 500 )
            );
        }
    }

    /**
     * Check rate limit for authentication endpoints
     *
     * @return bool|\WP_Error
     * @since 1.0.0
     */
    public static function check_rate_limit() {
        $client_ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
        $rate_limit_key = 'auth_rate_limit_' . md5( $client_ip );

        $current_count = get_transient( $rate_limit_key );
        if ( false === $current_count ) {
            $current_count = 0;
        }

        // Allow 5 attempts per 15 minutes
        if ( $current_count >= 5 ) {
            return new \WP_Error(
                'rate_limit_exceeded',
                'Too many authentication attempts. Please try again later.',
                array( 'status' => 429 )
            );
        }

        // Increment counter
        set_transient( $rate_limit_key, $current_count + 1, 900 ); // 15 minutes

        return true;
    }

    /**
     * Get user profile
     *
     * @param \WP_REST_Request $request The request object.
     * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure.
     * @since 1.0.0
     */
    public static function get_user_profile( $request ) {
        try {
            $current_user_id = get_current_user_id();

            if ( ! $current_user_id ) {
                return new \WP_Error(
                    'not_authenticated',
                    'User is not authenticated',
                    array( 'status' => 401 )
                );
            }

            $user = get_userdata( $current_user_id );

            if ( ! $user ) {
                return new \WP_Error(
                    'user_not_found',
                    'User not found',
                    array( 'status' => 404 )
                );
            }

            // Get additional user meta
            $user_meta = array(
                'phone' => get_user_meta( $current_user_id, 'basic_phone', true ),
                'gender' => get_user_meta( $current_user_id, 'basic_gender', true ),
                'dob' => get_user_meta( $current_user_id, 'basic_dob', true ),
                'address' => get_user_meta( $current_user_id, 'basic_address', true ),
                'city' => get_user_meta( $current_user_id, 'basic_city', true ),
                'state' => get_user_meta( $current_user_id, 'basic_state', true ),
                'country' => get_user_meta( $current_user_id, 'basic_country', true ),
                'postal_code' => get_user_meta( $current_user_id, 'basic_postal_code', true ),
            );

            $response_data = array(
                'success' => true,
                'data' => array(
                    'id' => $user->ID,
                    'username' => $user->user_login,
                    'email' => $user->user_email,
                    'first_name' => $user->first_name,
                    'last_name' => $user->last_name,
                    'display_name' => $user->display_name,
                    'registered' => $user->user_registered,
                    'roles' => $user->roles,
                    'capabilities' => self::get_user_api_capabilities( $user ),
                    'profile' => array_filter( $user_meta ), // Remove empty values
                ),
            );

            return new \WP_REST_Response( $response_data, 200 );

        } catch ( Exception $e ) {
            if ( class_exists( 'Care_API\\Utils\\Error_Handler' ) ) {
                \Care_API\Utils\Error_Handler::handle_exception( $e );
            }

            return new \WP_Error(
                'profile_error',
                'An error occurred while retrieving user profile',
                array( 'status' => 500 )
            );
        }
    }

    /**
     * Update user profile
     *
     * @param \WP_REST_Request $request The request object.
     * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure.
     * @since 1.0.0
     */
    public static function update_user_profile( $request ) {
        try {
            $current_user_id = get_current_user_id();

            if ( ! $current_user_id ) {
                return new \WP_Error(
                    'not_authenticated',
                    'User is not authenticated',
                    array( 'status' => 401 )
                );
            }

            $update_data = array();

            // Collect update data
            $allowed_fields = array( 'first_name', 'last_name', 'email' );
            foreach ( $allowed_fields as $field ) {
                if ( $request->has_param( $field ) ) {
                    $update_data[ $field ] = $request->get_param( $field );
                }
            }

            if ( empty( $update_data ) ) {
                return new \WP_Error(
                    'no_data_to_update',
                    'No valid data provided for update',
                    array( 'status' => 400 )
                );
            }

            // Update user data
            $update_data['ID'] = $current_user_id;
            $result = wp_update_user( $update_data );

            if ( is_wp_error( $result ) ) {
                return new \WP_Error(
                    'update_failed',
                    'Failed to update user profile: ' . $result->get_error_message(),
                    array( 'status' => 500 )
                );
            }

            // Log profile update
            if ( class_exists( 'Care_API\\Utils\\API_Logger' ) ) {
                \Care_API\Utils\API_Logger::log_info(
                    'User profile updated',
                    array(
                        'user_id' => $current_user_id,
                        'updated_fields' => array_keys( $update_data )
                    )
                );
            }

            return new \WP_REST_Response(
                array(
                    'success' => true,
                    'message' => 'Profile updated successfully'
                ),
                200
            );

        } catch ( Exception $e ) {
            if ( class_exists( 'Care_API\\Utils\\Error_Handler' ) ) {
                \Care_API\Utils\Error_Handler::handle_exception( $e );
            }

            return new \WP_Error(
                'profile_update_error',
                'An error occurred while updating user profile',
                array( 'status' => 500 )
            );
        }
    }

    /**
     * Handle forgot password request
     *
     * @param \WP_REST_Request $request The request object.
     * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure.
     * @since 1.0.0
     */
    public static function forgot_password( $request ) {
        try {
            $username = $request->get_param( 'username' );

            if ( empty( $username ) ) {
                return new \WP_Error(
                    'missing_username',
                    'Username or email is required',
                    array( 'status' => 400 )
                );
            }

            // Get user by login or email
            $user = get_user_by( 'login', $username );
            if ( ! $user && is_email( $username ) ) {
                $user = get_user_by( 'email', $username );
            }

            if ( ! $user ) {
                // Don't reveal if user exists or not for security
                return new \WP_REST_Response(
                    array(
                        'success' => true,
                        'message' => 'If the user exists, a password reset email has been sent.'
                    ),
                    200
                );
            }

            // Generate password reset key
            $key = get_password_reset_key( $user );

            if ( is_wp_error( $key ) ) {
                return new \WP_Error(
                    'reset_key_error',
                    'Could not generate password reset key',
                    array( 'status' => 500 )
                );
            }

            // Send password reset email
            $reset_url = add_query_arg(
                array(
                    'action' => 'rp',
                    'key'    => $key,
                    'login'  => rawurlencode( $user->user_login ),
                ),
                wp_login_url()
            );

            $message = sprintf(
                "Someone has requested a password reset for the following account:\n\n" .
                "Site Name: %s\n" .
                "Username: %s\n\n" .
                "If this was a mistake, just ignore this email and nothing will happen.\n\n" .
                "To reset your password, visit the following address:\n%s\n",
                get_option( 'blogname' ),
                $user->user_login,
                $reset_url
            );

            $sent = wp_mail(
                $user->user_email,
                sprintf( '[%s] Password Reset', get_option( 'blogname' ) ),
                $message
            );

            if ( ! $sent ) {
                return new \WP_Error(
                    'email_send_failed',
                    'Could not send password reset email',
                    array( 'status' => 500 )
                );
            }

            // Log password reset request
            if ( class_exists( 'Care_API\\Utils\\API_Logger' ) ) {
                \Care_API\Utils\API_Logger::log_info(
                    'Password reset requested',
                    array(
                        'user_id' => $user->ID,
                        'username' => $user->user_login,
                        'ip_address' => self::get_client_ip()
                    )
                );
            }

            return new \WP_REST_Response(
                array(
                    'success' => true,
                    'message' => 'Password reset email has been sent.'
                ),
                200
            );

        } catch ( Exception $e ) {
            if ( class_exists( 'Care_API\\Utils\\Error_Handler' ) ) {
                \Care_API\Utils\Error_Handler::handle_exception( $e );
            }

            return new \WP_Error(
                'forgot_password_error',
                'An error occurred while processing password reset request',
                array( 'status' => 500 )
            );
        }
    }

    /**
     * Handle password reset
     *
     * @param \WP_REST_Request $request The request object.
     * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure.
     * @since 1.0.0
     */
    public static function reset_password( $request ) {
        try {
            $key = $request->get_param( 'key' );
            $login = $request->get_param( 'login' );
            $password = $request->get_param( 'password' );

            if ( empty( $key ) || empty( $login ) || empty( $password ) ) {
                return new \WP_Error(
                    'missing_parameters',
                    'Key, login, and password are required',
                    array( 'status' => 400 )
                );
            }

            // Check password reset key
            $user = check_password_reset_key( $key, $login );

            if ( is_wp_error( $user ) ) {
                return new \WP_Error(
                    'invalid_reset_key',
                    'Invalid password reset key',
                    array( 'status' => 400 )
                );
            }

            // Update password
            wp_set_password( $password, $user->ID );

            // Log password reset
            if ( class_exists( 'Care_API\\Utils\\API_Logger' ) ) {
                \Care_API\Utils\API_Logger::log_info(
                    'Password reset completed',
                    array(
                        'user_id' => $user->ID,
                        'username' => $user->user_login,
                        'ip_address' => self::get_client_ip()
                    )
                );
            }

            return new \WP_REST_Response(
                array(
                    'success' => true,
                    'message' => 'Password has been reset successfully.'
                ),
                200
            );

        } catch ( Exception $e ) {
            if ( class_exists( 'Care_API\\Utils\\Error_Handler' ) ) {
                \Care_API\Utils\Error_Handler::handle_exception( $e );
            }

            return new \WP_Error(
                'password_reset_error',
                'An error occurred while resetting password',
                array( 'status' => 500 )
            );
        }
    }

    /**
     * Check authentication for protected endpoints
     *
     * @param \WP_REST_Request $request The request object.
     * @return bool|\WP_Error True if authenticated, WP_Error otherwise.
     * @since 1.0.0
     */
    public static function check_authentication( $request ) {
        // Use JWT middleware for authentication
        if ( class_exists( 'Care_API\\Middleware\\JWT_Middleware' ) ) {
            return \Care_API\Middleware\JWT_Middleware::authenticate( $request );
        }

        // Fallback to WordPress authentication
        $current_user_id = get_current_user_id();
        
        if ( ! $current_user_id ) {
            return new \WP_Error(
                'not_authenticated',
                'You are not authenticated',
                array( 'status' => 401 )
            );
        }

        return true;
    }

    /**
     * Validation helpers
     */

    /**
     * Validate username
     *
     * @param string $username Username to validate.
     * @return bool True if valid.
     * @since 1.0.0
     */
    public static function validate_username( $username ) {
        return ! empty( $username ) && ( is_email( $username ) || validate_username( $username ) );
    }

    /**
     * Validate password
     *
     * @param string $password Password to validate.
     * @return bool True if valid.
     * @since 1.0.0
     */
    public static function validate_password( $password ) {
        return ! empty( $password ) && strlen( $password ) >= 8;
    }

    /**
     * Utility methods
     */

    /**
     * Check if user can access API
     *
     * @param \WP_User $user User object.
     * @return bool True if user can access API.
     * @since 1.0.0
     */
    private static function user_can_access_api( $user ) {
        if ( ! $user || ! ( $user instanceof \WP_User ) ) {
            return false;
        }

        // Check for API access capability
        if ( $user->has_cap( 'care_api_access' ) ) {
            return true;
        }

        // Allow specific roles
        $allowed_roles = array( 'administrator', 'kivicare_doctor', 'kivicare_receptionist', 'kivicare_patient' );
        
        foreach ( $allowed_roles as $role ) {
            if ( in_array( $role, $user->roles ) ) {
                return true;
            }
        }

        return false;
    }

    /**
     * Check if user account is active
     *
     * @param \WP_User $user User object.
     * @return bool True if user is active.
     * @since 1.0.0
     */
    private static function is_user_active( $user ) {
        if ( ! $user || ! ( $user instanceof \WP_User ) ) {
            return false;
        }

        // Check user status meta
        $user_status = get_user_meta( $user->ID, 'account_status', true );
        
        return empty( $user_status ) || $user_status === 'active';
    }

    /**
     * Get user API capabilities
     *
     * @param \WP_User $user User object.
     * @return array User API capabilities.
     * @since 1.0.0
     */
    private static function get_user_api_capabilities( $user ) {
        $capabilities = array();

        if ( ! $user || ! ( $user instanceof \WP_User ) ) {
            return $capabilities;
        }

        // Define role-based capabilities
        $role_capabilities = array(
            'administrator' => array(
                'read_clinics', 'create_clinics', 'update_clinics', 'delete_clinics',
                'read_doctors', 'create_doctors', 'update_doctors', 'delete_doctors',
                'read_patients', 'create_patients', 'update_patients', 'delete_patients',
                'read_appointments', 'create_appointments', 'update_appointments', 'delete_appointments',
                'read_encounters', 'create_encounters', 'update_encounters', 'delete_encounters',
                'read_prescriptions', 'create_prescriptions', 'update_prescriptions', 'delete_prescriptions',
                'read_bills', 'create_bills', 'update_bills', 'delete_bills',
                'read_reports', 'manage_settings'
            ),
            'kivicare_doctor' => array(
                'read_clinics',
                'read_patients', 'update_patients',
                'read_appointments', 'update_appointments',
                'read_encounters', 'create_encounters', 'update_encounters',
                'read_prescriptions', 'create_prescriptions', 'update_prescriptions',
                'read_bills'
            ),
            'kivicare_receptionist' => array(
                'read_clinics',
                'read_patients', 'create_patients', 'update_patients',
                'read_doctors',
                'read_appointments', 'create_appointments', 'update_appointments',
                'read_encounters',
                'read_bills', 'create_bills', 'update_bills'
            ),
            'kivicare_patient' => array(
                'read_appointments',
                'read_encounters',
                'read_prescriptions',
                'read_bills'
            )
        );

        // Get capabilities based on user roles
        foreach ( $user->roles as $role ) {
            if ( isset( $role_capabilities[ $role ] ) ) {
                $capabilities = array_merge( $capabilities, $role_capabilities[ $role ] );
            }
        }

        return array_unique( $capabilities );
    }

    /**
     * Get token from request
     *
     * @param \WP_REST_Request $request Request object.
     * @return string|null Token or null if not found.
     * @since 1.0.0
     */
    private static function get_token_from_request( $request ) {
        $auth_header = $request->get_header( 'authorization' );
        
        if ( $auth_header && strpos( $auth_header, 'Bearer ' ) === 0 ) {
            return substr( $auth_header, 7 );
        }

        return null;
    }

    /**
     * Get token expiry time
     *
     * @param string $token JWT token.
     * @return string|null Token expiry time or null.
     * @since 1.0.0
     */
    private static function get_token_expiry( $token ) {
        if ( class_exists( 'Care_API\\Services\\JWT_Service' ) ) {
            return \Care_API\Services\JWT_Service::get_token_expiry( $token );
        }

        return null;
    }

    /**
     * Get client IP address
     *
     * @return string Client IP address.
     * @since 1.0.0
     */
    private static function get_client_ip() {
        $ip_keys = array( 'HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR' );
        
        foreach ( $ip_keys as $key ) {
            if ( array_key_exists( $key, $_SERVER ) === true ) {
                $ip_list = explode( ',', $_SERVER[ $key ] );
                foreach ( $ip_list as $ip ) {
                    $ip = trim( $ip );
                    if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
                        return $ip;
                    }
                }
            }
        }
        
        return $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
    }
}