<?php
namespace OxygenApp\Controllers;

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

use OxygenApp\Utils\FrontendData;
use OxygenApp\Utils\OptionUtils;
use OxygenApp\Models\User;
use OxygenApp\Utils\UserUtil;

class GoogleAuthCtrl {

    static function generateRedirect(\WP_REST_Request $request): \WP_REST_Response {
        if (!FrontendData::isGoogleSignInActive()) {
            return new \WP_REST_Response(['message' => esc_html__('Google Sign-In is not set up.', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        $client_id = trim(OptionUtils::getInstance()->getOption('google_client_id'));
        $redirect_uri = FrontendData::getGoogleOAuthCallbackUrl();

        // Generate cryptographically secure state parameter
        $state = bin2hex(random_bytes(32));

        // Store state in transient (expires in 10 minutes = 600 seconds)
        set_transient('google_oauth_state_' . $state, true, 600);

        $auth_url = "https://accounts.google.com/o/oauth2/auth?" . http_build_query([
            'client_id'     => $client_id,
            'redirect_uri'  => $redirect_uri,
            'response_type' => 'code',
            'scope'         => 'email profile',
            'state'         => $state,
        ]);

        return new \WP_REST_Response(['auth_url' => $auth_url], 200);
    }

    static function handleOAuthCallback() {
        // Validate state parameter first (CSRF protection)
        if (!isset($_GET['state'])) {
            return new \WP_REST_Response(['message' => esc_html__('Missing state parameter', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        $state = sanitize_text_field(wp_unslash($_GET['state']));

        // Verify state was generated by us
        if (!get_transient('google_oauth_state_' . $state)) {
            return new \WP_REST_Response(['message' => esc_html__('Invalid or expired state parameter', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        // Delete state (single-use token)
        delete_transient('google_oauth_state_' . $state);

        // Now validate authorization code
        if (!isset($_GET['code'])) {
            return new \WP_REST_Response(['message' => 'Authorization code missing'], 400);
        }

        if (!OptionUtils::getInstance()->getOption('is_google_signin_active')) {
            return new \WP_REST_Response(['message' => 'Google sign in is not active'], 400);
        }

        $client_id = trim(OptionUtils::getInstance()->getOption('google_client_id'));
        $client_secret = trim(OptionUtils::getInstance()->getOption('google_client_secret'));
        $redirect_uri = FrontendData::getGoogleOAuthCallbackUrl();
        $code = sanitize_text_field(wp_unslash($_GET['code']));

        // Exchange code for access token
        $response = wp_remote_post('https://oauth2.googleapis.com/token', [
            'body' => [
                'client_id'     => $client_id,
                'client_secret' => $client_secret,
                'redirect_uri'  => $redirect_uri,
                'code'          => $code,
                'grant_type'    => 'authorization_code',
            ],
        ]);

        if (is_wp_error($response)) {
            return new \WP_REST_Response(['message' => 'Token request failed'], 400);
        }

        $body = json_decode(wp_remote_retrieve_body($response), true);
        if (empty($body['access_token'])) {
            return new \WP_REST_Response(['message' => 'Failed to get access token'], 400);
        }

        // Fetch user info
        $user_info = wp_remote_get('https://www.googleapis.com/oauth2/v2/userinfo', [
            'headers' => ['Authorization' => 'Bearer ' . $body['access_token']],
        ]);

        if (is_wp_error($user_info)) {
            return new \WP_REST_Response(['message' => 'Failed to fetch user info'], 400);
        }

        $user_data = json_decode(wp_remote_retrieve_body($user_info), true);
        if (empty($user_data['email'])) {
            return new \WP_REST_Response(['message' => 'Failed to fetch user email'], 400);
        }

        if (!is_email($user_data['email'])) {
            return new \WP_REST_Response(['message' => 'Invalid user email'], 400);
        }
        

        $userData = null;

        $g_email = $user_data['email'];
        $g_name = $user_data['name'] ?? '';

        $user = new User();
        $userExists = $user->find('email', $g_email);
        if ($userExists) {
            $userData = $userExists;
        } else {
            $result = $user->create([
                'email' => $g_email,
                'name' => sanitize_text_field($g_name),
                'password' => wp_generate_password(20, false),
                'activation_code' => wp_generate_password(20, false),
                'terms' => 'yes',
                'is_active' => 1, 
            ]);
            if (is_numeric($result)) {
                $userData = $user->findById($result);
            }
        }

        $user->update($userData['id'], [
            'last_login_time' => current_time('mysql', true)
        ]);

        UserUtil::login($userData, true);
        wp_safe_redirect(FrontendData::getAppPageUrl());
        exit;
        // wp_die(); // does not seem to work properly
    }
}
