<?php
/**
 * DESCRIPTION: REST API controller for Google Calendar OAuth connect, callback, disconnect, and status endpoints.
 * Credentials (Client ID/Secret) are entered by the site owner in the plugin Settings UI.
 *
 * @package NemtlyBooking\API
 */

namespace NemtlyBooking\API;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use NemtlyBooking\Integrations\Google\Google_OAuth_Provider;

/**
 * Google Auth Controller
 *
 * Exposes REST endpoints for the Google Calendar OAuth flow:
 *   GET  /nemtly-booking/v1/google-auth/status      — connection status + redirect URI
 *   GET  /nemtly-booking/v1/google-auth/connect     — returns the Google OAuth URL
 *   GET  /nemtly-booking/v1/google-auth/callback    — handles the redirect-back from Google
 *   POST /nemtly-booking/v1/google-auth/disconnect  — revokes tokens and disconnects
 *
 * @since PBOOKING_SINCE
 */
class Google_Auth_Controller extends Nemtly_API {

    /**
     * OAuth provider instance.
     *
     * @var Google_OAuth_Provider
     */
    private $oauth_provider;

    /**
     * Constructor
     *
     * @since PBOOKING_SINCE
     *
     * @param Google_OAuth_Provider $oauth_provider OAuth provider instance.
     */
    public function __construct( Google_OAuth_Provider $oauth_provider ) {
        parent::__construct();
        $this->rest_base      = 'google-auth';
        $this->oauth_provider = $oauth_provider;
    }

    /**
     * Register REST API routes
     *
     * @since PBOOKING_SINCE
     */
    public function register_routes() {
        // Connection status + redirect URI helper.
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/status',
            [
                'methods'             => 'GET',
                'callback'            => [ $this, 'get_status' ],
                'permission_callback' => [ $this, 'check_admin_permissions' ],
            ]
        );

        // Return the Google OAuth authorization URL.
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/connect',
            [
                'methods'             => 'GET',
                'callback'            => [ $this, 'get_connect_url' ],
                'permission_callback' => [ $this, 'check_admin_permissions' ],
            ]
        );

        // Handle Google's redirect back after the user grants consent.
        // Must be publicly accessible (no auth) because Google redirects here before the admin is re-authenticated.
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/callback',
            [
                'methods'             => 'GET',
                'callback'            => [ $this, 'handle_callback' ],
                'permission_callback' => '__return_true',
            ]
        );

        // Disconnect: revoke token and remove stored credentials.
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/disconnect',
            [
                'methods'             => 'POST',
                'callback'            => [ $this, 'disconnect' ],
                'permission_callback' => [ $this, 'check_admin_permissions' ],
            ]
        );
    }

    /**
     * Return connection status and the redirect URI the site owner needs for Google Cloud Console.
     *
     * @since PBOOKING_SINCE
     *
     * @param WP_REST_Request $request Request object.
     *
     * @return WP_REST_Response
     */
    public function get_status( $request ) {
        $settings     = get_option( 'nemtly_booking_settings', [] );
        $has_creds    = ! empty( $settings['google_client_id'] ) && ! empty( $settings['google_client_secret'] );
        $is_connected = $has_creds && $this->oauth_provider->is_connected();
        $calendar_id  = get_option( Google_OAuth_Provider::CALENDAR_ID_OPTION, 'primary' );

        return new WP_REST_Response(
            [
                'success' => true,
                'data'    => [
                    'connected'    => $is_connected,
                    'has_creds'    => $has_creds,
                    'redirect_uri' => $this->oauth_provider->get_redirect_uri(),
                    'calendar_id'  => $calendar_id,
                ],
            ],
            200
        );
    }

    /**
     * Return the Google OAuth authorization URL.
     *
     * @since PBOOKING_SINCE
     *
     * @param WP_REST_Request $request Request object.
     *
     * @return WP_REST_Response|WP_Error
     */
    public function get_connect_url( $request ) {
        $auth_url = $this->oauth_provider->get_authorization_url();

        if ( ! $auth_url ) {
            return new WP_Error(
                'google_missing_credentials',
                __( 'Google Client ID and Client Secret must be saved before connecting.', 'nemtly-booking' ),
                [ 'status' => 400 ]
            );
        }

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

    /**
     * Handle the OAuth callback redirect from Google.
     *
     * Exchanges the authorization code for tokens, stores them,
     * then redirects the admin back to the Settings → Integrations tab.
     *
     * @since PBOOKING_SINCE
     *
     * @param WP_REST_Request $request Request object.
     *
     * @return void  (issues a wp_safe_redirect and exits)
     */
    public function handle_callback( $request ) {
        $code  = sanitize_text_field( wp_unslash( $request->get_param( 'code' ) ?? '' ) );
        $error = sanitize_text_field( wp_unslash( $request->get_param( 'error' ) ?? '' ) );

        $settings_url = add_query_arg(
            [
                'page' => 'nemtly-booking-settings',
                'tab'  => 'integrations',
            ],
            admin_url( 'admin.php' )
        );

        if ( $error || empty( $code ) ) {
            wp_safe_redirect(
                add_query_arg( 'google_auth_error', '1', $settings_url )
            );
            exit;
        }

        $success = $this->oauth_provider->exchange_code_for_token( $code );

        if ( ! $success ) {
            wp_safe_redirect(
                add_query_arg( 'google_auth_error', '1', $settings_url )
            );
            exit;
        }

        wp_safe_redirect(
            add_query_arg( 'google_auth_success', '1', $settings_url )
        );
        exit;
    }

    /**
     * Revoke and delete stored Google OAuth tokens.
     *
     * @since PBOOKING_SINCE
     *
     * @param WP_REST_Request $request Request object.
     *
     * @return WP_REST_Response
     */
    public function disconnect( $request ) {
        $this->oauth_provider->disconnect();

        return new WP_REST_Response(
            [
                'success' => true,
                'message' => __( 'Google Calendar disconnected successfully.', 'nemtly-booking' ),
            ],
            200
        );
    }

    /**
     * Check admin permissions
     *
     * @since PBOOKING_SINCE
     *
     * @return bool
     */
    public function check_admin_permissions() {
        return current_user_can( 'manage_options' );
    }
}
