<?php

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

class AIEO_SSO_Rest {

    
    private static $providers = null;

    public static function register() {
        add_action('rest_api_init', array(__CLASS__, 'register_routes'));
    }

    public static function register_routes() {
        register_rest_route('aieo/v1', '/social-login/(?P<provider>[a-z0-9_-]+)/start', array(
            'methods'             => 'GET',
            'callback'            => array(__CLASS__, 'handle_start'),
            'permission_callback' => '__return_true',
            'args'                => array('provider' => array('type' => 'string', 'required' => true)),
        ));
        
        register_rest_route('aieo/v1', '/social-login/(?P<provider>[a-z0-9_-]+)/callback', array(
            'methods'             => array('GET', 'POST'),
            'callback'            => array(__CLASS__, 'handle_callback'),
            'permission_callback' => '__return_true',
            'args'                => array('provider' => array('type' => 'string', 'required' => true)),
        ));
        
        
        
        register_rest_route('aieo/v1', '/sso/onetap', array(
            'methods'             => 'POST',
            'callback'            => array(__CLASS__, 'handle_onetap'),
            'permission_callback' => '__return_true',
            'args'                => array(
                'id_token' => array('type' => 'string', 'required' => true),
            ),
        ));
    }

    public static function handle_start(WP_REST_Request $request) {
        $code = sanitize_key((string) $request->get_param('provider'));
        $provider = self::resolve_provider($code);
        if ($provider instanceof WP_Error) { return $provider; }

        $intent      = sanitize_key((string) $request->get_param('intent'));
        if (!in_array($intent, array('login', 'connect', 'subscribe'), true)) { $intent = 'login'; }
        $redirect_to = (string) $request->get_param('redirect_to');
        if ($redirect_to === '') { $redirect_to = (string) wp_get_referer() ?: home_url('/'); }

        
        if ($intent === 'connect' && !is_user_logged_in()) {
            return new WP_Error('sso_not_logged_in', __('You must be logged in to connect a social account.', 'ai-eshop-optimizer'), array('status' => 401));
        }

        $state = AIEO_SSO_State::issue($intent, $redirect_to, get_current_user_id());
        $url   = $provider->auth_url($state, AIEO_SSO_Buttons_Data::callback_url($code));
        if (is_wp_error($url)) { return $url; }

        
        
        wp_redirect($url);
        exit;
    }

    public static function handle_callback(WP_REST_Request $request) {
        $code_provider = sanitize_key((string) $request->get_param('provider'));
        $provider = self::resolve_provider($code_provider);
        if ($provider instanceof WP_Error) { return $provider; }

        
        $err = (string) $request->get_param('error');
        if ($err !== '') {
            return self::redirect_with_notice(home_url('/'), 'error', sprintf('Σύνδεση μέσω %s ακυρώθηκε.', $provider->label()));
        }

        $auth_code = (string) $request->get_param('code');
        $state_q   = (string) $request->get_param('state');
        if ($auth_code === '' || $state_q === '') {
            return new WP_Error('sso_missing_params', __('Missing code or state.', 'ai-eshop-optimizer'), array('status' => 400));
        }

        $payload = AIEO_SSO_State::verify($state_q);
        if ($payload instanceof WP_Error) {
            return self::redirect_with_notice(home_url('/'), 'error', self::friendly_message($payload, $provider));
        }

        $intent      = (string) ($payload['intent']      ?? 'login');
        $redirect_to = (string) ($payload['redirect_to'] ?? home_url('/'));

        $token = $provider->exchange_token($auth_code, AIEO_SSO_Buttons_Data::callback_url($code_provider));
        if (is_wp_error($token)) {
            return self::redirect_with_notice($redirect_to, 'error', self::friendly_message($token, $provider));
        }

        $profile = $provider->fetch_profile($token);
        if (is_wp_error($profile)) {
            return self::redirect_with_notice($redirect_to, 'error', self::friendly_message($profile, $provider));
        }

        switch ($intent) {
            case 'connect':
                $current_user_id = (int) ($payload['uid'] ?? get_current_user_id());
                if ($current_user_id <= 0) {
                    return self::redirect_with_notice($redirect_to, 'error', 'Πρέπει να είστε συνδεδεμένος.');
                }
                AIEO_SSO_Account_Linker::write_link_meta(
                    $current_user_id,
                    $code_provider,
                    (string) $profile['provider_uid'],
                    (string) ($profile['email']  ?? ''),
                    (string) ($profile['avatar'] ?? '')
                );
                return self::redirect_with_notice($redirect_to, 'success', sprintf('Συνδέθηκε ο λογαριασμός %s.', $provider->label()));

            case 'subscribe':
                
                
                
                $email = (string) ($profile['email'] ?? '');
                if ($email === '') {
                    return self::redirect_with_notice($redirect_to, 'error', 'Δεν ελάβαμε email από τον πάροχο.');
                }
                
                do_action('aieo_sso_subscribe_intent', $email, $code_provider, $profile);
                return self::redirect_with_notice($redirect_to, 'success', sprintf('Εγγραφήκατε με %s.', $provider->label()));

            case 'login':
            default:
                $user_id = AIEO_SSO_Account_Linker::find_or_create($code_provider, $profile);
                if (is_wp_error($user_id)) {
                    return self::redirect_with_notice($redirect_to, 'error', self::friendly_message($user_id, $provider));
                }
                wp_set_current_user($user_id);
                wp_set_auth_cookie($user_id, true);
                
                do_action('aieo_sso_user_logged_in', $user_id, $code_provider, $profile);
                return self::redirect_with_notice($redirect_to, 'success', sprintf('Καλώς ήρθατε.', $provider->label()));
        }
    }

    
    public static function handle_onetap(WP_REST_Request $request) {
        
        $cs = get_option('aieo_consent_settings', array());
        if (($cs['one_tap_enabled'] ?? '') !== 'yes') {
            return new WP_REST_Response(array('ok' => false, 'reason' => 'disabled'), 200);
        }
        
        if (class_exists('AIEO_Consent') && !AIEO_Consent::allows('personalize')) {
            return new WP_REST_Response(array('ok' => false, 'reason' => 'no-consent'), 200);
        }
        $provider = self::resolve_provider('google');
        if ($provider instanceof WP_Error || !method_exists($provider, 'verify_id_token')) {
            return new WP_REST_Response(array('ok' => false, 'reason' => 'provider'), 200);
        }
        $profile = $provider->verify_id_token((string) $request->get_param('id_token'));
        if (is_wp_error($profile)) {
            return new WP_REST_Response(array('ok' => false, 'reason' => 'verify'), 200);
        }
        $email = (string) ($profile['email'] ?? '');
        if ($email === '' || !is_email($email)) {
            return new WP_REST_Response(array('ok' => false, 'reason' => 'no-email'), 200);
        }
        if (!class_exists('AIEO_Push_Identity')) {
            require_once AIEO_DIR . 'includes/dmm/push/class-aieo-push-identity.php';
        }
        $name = trim((string) ($profile['first_name'] ?? '') . ' ' . (string) ($profile['last_name'] ?? ''));
        $res  = AIEO_Push_Identity::identify_by_email($email, $name);
        return new WP_REST_Response(array(
            'ok'         => true,
            'recognised' => true,
            'matched'    => !empty($res['matched']),   
            'first_name' => (string) ($profile['first_name'] ?? ''),
        ), 200);
    }

    
    private static function providers() {
        if (self::$providers !== null) { return self::$providers; }
        self::$providers = apply_filters('aieo_sso_providers', array());
        return self::$providers;
    }

    private static function resolve_provider($code) {
        $providers = self::providers();
        if (!isset($providers[$code])) {
            
            return new WP_Error('sso_unknown_provider', sprintf( __( 'Unknown SSO provider: %s', 'ai-eshop-optimizer' ), $code), array('status' => 404));
        }
        $creds = $providers[$code]->credentials();
        if (empty($creds['enabled']) || $creds['client_id'] === '' || $creds['client_secret'] === '') {
            
            return new WP_Error('sso_provider_disabled', sprintf( __( 'Provider %s is not configured.', 'ai-eshop-optimizer' ), $code), array('status' => 503));
        }
        return $providers[$code];
    }

    
    private static function friendly_message(WP_Error $err, $provider) {
        $code  = (string) $err->get_error_code();
        $label = is_object($provider) && method_exists($provider, 'label') ? $provider->label() : 'social login';
        switch ($code) {
            case 'registration-error-email-exists':
            case 'existing_user_email':
                return sprintf('Υπάρχει ήδη λογαριασμός με αυτό το email. Συνδεθείτε με τον κωδικό σας ή χρησιμοποιήστε άλλο email για %s.', $label);
            case 'sso_state_expired':
                return 'Η σύνδεση έληξε. Δοκιμάστε ξανά.';
            case 'sso_state_mismatch':
            case 'sso_state_signature':
            case 'sso_state_missing':
            case 'sso_state_format':
            case 'sso_state_payload':
                return 'Η σύνδεση δεν μπορεί να επαληθευθεί. Δοκιμάστε ξανά.';
            case 'sso_no_provider_uid':
                return sprintf('Ο πάροχος %s δεν επέστρεψε αναγνωριστικό λογαριασμού.', $label);
            case 'sso_no_token':
                return sprintf('Δεν λάβαμε token από %s.', $label);
            default:
                
                $msg = (string) $err->get_error_message();
                return $msg !== '' ? $msg : sprintf('Η σύνδεση μέσω %s απέτυχε.', $label);
        }
    }

    private static function redirect_with_notice($url, $kind, $msg) {
        $url = add_query_arg(array(
            'aieo_sso_notice' => rawurlencode((string) $msg),
            'aieo_sso_kind'   => sanitize_key((string) $kind),
        ), (string) $url);
        wp_safe_redirect($url);
        exit;
    }
}
