<?php
/**
 * Plugin Name: ACC JWT Auth
 * Description: سیستم احراز هویت JWT برای API پنل ACC
 * Version: 1.1.0
 */

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

/**
 * کلید مخفی JWT — فقط اگر از قبل (config/secrets) تعریف نشده باشد
 */
if ( ! defined( 'ACC_JWT_SECRET' ) ) {
    $secrets = dirname( __DIR__ ) . '/standalone/secrets.local.php';
    if ( is_file( $secrets ) ) {
        require_once $secrets;
    }
}
if ( ! defined( 'ACC_JWT_SECRET' ) ) {
    // هرگز سکرت ثابت در ریپو نگذارید
    define( 'ACC_JWT_SECRET', getenv( 'ACC_JWT_SECRET' ) ?: hash( 'sha256', __DIR__ . '|jwt-fallback-change-me' ) );
}


/*
|--------------------------------------------------------------------------
| ثبت Route ها
|--------------------------------------------------------------------------
*/

add_action('rest_api_init', function () {

    register_rest_route('acc/v1', '/auth/login', [
        'methods'  => 'POST',
        'callback' => 'acc_jwt_handle_login',
        'permission_callback' => '__return_true'
    ]);

    register_rest_route('acc/v1', '/auth/me', [
        'methods'  => 'GET',
        'callback' => 'acc_jwt_handle_me',
        'permission_callback' => 'acc_jwt_check_permission'
    ]);

});


/*
|--------------------------------------------------------------------------
| JWT Helpers
|--------------------------------------------------------------------------
*/

function acc_jwt_base64_url_encode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function acc_jwt_base64_url_decode($data) {
    return base64_decode(strtr($data, '-_', '+/') . str_repeat('=', 3 - (3 + strlen($data)) % 4));
}


function acc_jwt_generate_token($user_or_id, $remember = false) {

    // هم WP_User و هم user_id را قبول می‌کند
    $user_id = is_object($user_or_id) ? $user_or_id->ID : (int) $user_or_id;

    $header = json_encode([
        'typ' => 'JWT',
        'alg' => 'HS256'
    ]);

    $payload = json_encode([
        'sub' => $user_id,
        'iat' => time(),
        'exp' => time() + DAY_IN_SECONDS * 7
    ]);

    $base64Header = acc_jwt_base64_url_encode($header);
    $base64Payload = acc_jwt_base64_url_encode($payload);

    $signature = hash_hmac(
        'sha256',
        $base64Header . "." . $base64Payload,
        ACC_JWT_SECRET,
        true
    );

    $base64Signature = acc_jwt_base64_url_encode($signature);

    return $base64Header . "." . $base64Payload . "." . $base64Signature;
}


function acc_jwt_validate_token($token) {

    $parts = explode('.', $token);

    if (count($parts) !== 3) {
        return false;
    }

    list($header, $payload, $signature) = $parts;

    $expected = hash_hmac(
        'sha256',
        $header . "." . $payload,
        ACC_JWT_SECRET,
        true
    );

    if (!hash_equals(acc_jwt_base64_url_encode($expected), $signature)) {
        return false;
    }

    $data = json_decode(acc_jwt_base64_url_decode($payload), true);

    if (!$data) {
        return false;
    }

    if (isset($data['exp']) && time() > $data['exp']) {
        return false;
    }

    return $data;
}


/*
|--------------------------------------------------------------------------
| دریافت Authorization Header
|--------------------------------------------------------------------------
*/

function acc_jwt_get_authorization_header() {

    if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
        return trim($_SERVER["HTTP_AUTHORIZATION"]);
    }

    if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
        return trim($_SERVER["REDIRECT_HTTP_AUTHORIZATION"]);
    }

    if (function_exists('apache_request_headers')) {

        $headers = apache_request_headers();

        foreach ($headers as $key => $value) {

            if (strtolower($key) === 'authorization') {
                return trim($value);
            }
        }
    }

    return '';
}


/*
|--------------------------------------------------------------------------
| استخراج user از JWT
|--------------------------------------------------------------------------
*/

function acc_jwt_get_user_from_request() {

    $auth = acc_jwt_get_authorization_header();

    if (!$auth) {
        return 0;
    }

    if (!preg_match('/Bearer\s(\S+)/', $auth, $matches)) {
        return 0;
    }

    $data = acc_jwt_validate_token($matches[1]);

    if (!$data || !isset($data['sub'])) {
        return 0;
    }

    return intval($data['sub']);
}


/*
|--------------------------------------------------------------------------
| Login Handler
|--------------------------------------------------------------------------
*/

function acc_jwt_handle_login($request) {

    $username = $request->get_param('username');
    $password = $request->get_param('password');

    $user = wp_authenticate($username, $password);

    if (is_wp_error($user)) {

        return new WP_Error(
            'jwt_auth_failed',
            'نام کاربری یا رمز عبور اشتباه است',
            ['status' => 403]
        );
    }

    return [
        'success' => true,
        'token' => acc_jwt_generate_token($user->ID),
        'user' => [
            'id' => $user->ID,
            'username' => $user->user_login,
            'display_name' => $user->display_name,
            'roles' => $user->roles
        ]
    ];
}


/*
|--------------------------------------------------------------------------
| Me Endpoint
|--------------------------------------------------------------------------
*/

function acc_jwt_handle_me() {

    $user_id = acc_jwt_get_user_from_request();

    if (!$user_id) {

        return new WP_Error(
            'rest_forbidden',
            'توکن نامعتبر است',
            ['status' => 403]
        );
    }

    $user = get_userdata($user_id);

    if (!$user) {

        return new WP_Error(
            'rest_forbidden',
            'کاربر یافت نشد',
            ['status' => 403]
        );
    }

    return [
        'id' => $user->ID,
        'username' => $user->user_login,
        'roles' => $user->roles
    ];
}


/*
|--------------------------------------------------------------------------
| Permission Callback
|--------------------------------------------------------------------------
*/

function acc_jwt_check_permission() {

    $user_id = acc_jwt_get_user_from_request();

    if ($user_id > 0) {

        wp_set_current_user($user_id);

        return true;
    }

    return new WP_Error(
        'rest_forbidden',
        'دسترسی غیرمجاز',
        ['status' => 403]
    );
}


/*
|--------------------------------------------------------------------------
| JWT Middleware برای تمام acc/v1
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| JWT Middleware برای تمام acc/v1  (با لاگ کامل)
|--------------------------------------------------------------------------
*/

add_filter('rest_request_before_callbacks', function ($response, $handler, $request) {

    $route = $request->get_route();

    // اگر این namespace نبود → عبور
    if (strpos($route, '/acc/v1/') !== 0) {
        return $response;
    }

    // مسیرهای عمومی — بدون نیاز به JWT
    if (
        strpos($route, '/acc/v1/public/') === 0       ||
        $route === '/acc/v1/auth/login'                ||
        strpos($route, '/acc/v1/chat/support/') === 0  ||
        strpos($route, '/acc/v1/chat/visitor/') === 0
    ) {
        return $response;
    }

    // بررسی JWT
    $user_id = acc_jwt_get_user_from_request();

    if (!$user_id) {
        return new WP_Error(
            'rest_forbidden',
            'توکن ارسال نشده یا نامعتبر است',
            ['status' => 403]
        );
    }

    wp_set_current_user($user_id);
    $GLOBALS['acc_jwt_user_id'] = $user_id;

    return $response;

}, 10, 3);

