<?php
/**
 * WP REST API proxy for Gutenberg block.
 *
 * @package GoValid_QR
 */

defined( 'ABSPATH' ) || exit;

class GoValid_Rest_Controller {

	private const NAMESPACE = 'govalid-qr/v1';

	/**
	 * Register hooks.
	 */
	public function register(): void {
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
	}

	/**
	 * Register REST routes.
	 */
	public function register_routes(): void {
		register_rest_route( self::NAMESPACE, '/qr-codes', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'list_qr_codes' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'page'     => array(
					'type'              => 'integer',
					'default'           => 1,
					'sanitize_callback' => 'absint',
				),
				'per_page' => array(
					'type'              => 'integer',
					'default'           => 20,
					'sanitize_callback' => 'absint',
				),
				'search'   => array(
					'type'              => 'string',
					'default'           => '',
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );

		register_rest_route( self::NAMESPACE, '/qr-codes/(?P<uuid>[a-zA-Z0-9-]+)', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_qr_code' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'uuid' => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );

		register_rest_route( self::NAMESPACE, '/qr-codes', array(
			'methods'             => 'POST',
			'callback'            => array( $this, 'create_qr_code' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		register_rest_route( self::NAMESPACE, '/ad-track', array(
			'methods'             => 'POST',
			'callback'            => array( $this, 'track_ad' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'ad_id'  => array(
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'action' => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_key',
				),
			),
		) );

		register_rest_route( self::NAMESPACE, '/stats', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_stats' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		register_rest_route( self::NAMESPACE, '/status', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_status' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		register_rest_route( self::NAMESPACE, '/subscription', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_subscription' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		register_rest_route( self::NAMESPACE, '/numbering/patterns', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_numbering_patterns' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		register_rest_route( self::NAMESPACE, '/numbering/generate', array(
			'methods'             => 'POST',
			'callback'            => array( $this, 'generate_numbering' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		register_rest_route( self::NAMESPACE, '/pin/status', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_pin_status' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		register_rest_route( self::NAMESPACE, '/pin/verify', array(
			'methods'             => 'POST',
			'callback'            => array( $this, 'verify_pin' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		register_rest_route( self::NAMESPACE, '/tags', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_tags' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		register_rest_route( self::NAMESPACE, '/analytics', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_analytics' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		register_rest_route( self::NAMESPACE, '/analytics/(?P<uuid>[a-zA-Z0-9-]+)', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_qr_analytics' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'uuid' => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );

		register_rest_route( self::NAMESPACE, '/qr-codes/(?P<uuid>[a-zA-Z0-9-]+)', array(
			'methods'             => 'DELETE',
			'callback'            => array( $this, 'delete_qr_code' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'uuid' => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );
	}

	/**
	 * List QR codes.
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response|WP_Error
	 */
	public function list_qr_codes( WP_REST_Request $request ) {
		$api    = new GoValid_QR_API();
		$result = $api->list_qr_codes(
			$request->get_param( 'page' ),
			$request->get_param( 'per_page' ),
			$request->get_param( 'search' )
		);

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

		return rest_ensure_response( $result );
	}

	/**
	 * Get a single QR code.
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_qr_code( WP_REST_Request $request ) {
		$api    = new GoValid_QR_API();
		$result = $api->get_qr_detail( $request->get_param( 'uuid' ) );

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

		return rest_ensure_response( $result );
	}

	/**
	 * Create a QR code.
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response|WP_Error
	 */
	public function create_qr_code( WP_REST_Request $request ) {
		$body = $request->get_json_params();
		$type = isset( $body['type'] ) ? sanitize_text_field( $body['type'] ) : 'url';
		$name = isset( $body['name'] ) ? sanitize_text_field( $body['name'] ) : '';
		$data = isset( $body['data'] ) ? (array) $body['data'] : array();

		$api    = new GoValid_QR_API();
		$result = $api->create_qr_code( $type, $name, $data );

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

		// Flush list cache.
		GoValid_Cache::get_instance()->delete( 'qr_list' );

		return rest_ensure_response( $result );
	}

	/**
	 * Get dashboard stats.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_stats() {
		$api    = new GoValid_QR_API();
		$result = $api->get_dashboard_stats();

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

		return rest_ensure_response( $result );
	}

	/**
	 * Get connection status.
	 *
	 * @return WP_REST_Response
	 */
	public function get_status() {
		return rest_ensure_response( array(
			'connected' => GoValid_QR::is_connected(),
			'userinfo'  => get_option( 'govalid_qr_userinfo', array() ),
		) );
	}

	/**
	 * Get subscription and quota information.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_subscription() {
		if ( ! GoValid_QR::is_connected() ) {
			return new WP_Error(
				'govalid_not_connected',
				__( 'Not connected to GoValid.', 'govalid-qr' ),
				array( 'status' => 403 )
			);
		}

		$api    = new GoValid_QR_API();
		$result = $api->get_subscription();

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

		return rest_ensure_response( $result );
	}

	/**
	 * Get institution numbering patterns.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_numbering_patterns() {
		$api    = new GoValid_QR_API();
		$result = $api->get_numbering_patterns();

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

		return rest_ensure_response( $result );
	}

	/**
	 * Generate numbers from an institution pattern.
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response|WP_Error
	 */
	public function generate_numbering( WP_REST_Request $request ) {
		$body       = $request->get_json_params();
		$pattern_id = isset( $body['pattern_id'] ) ? absint( $body['pattern_id'] ) : 0;
		$quantity   = isset( $body['quantity'] ) ? absint( $body['quantity'] ) : 1;

		if ( ! $pattern_id ) {
			return new WP_Error( 'missing_pattern', __( 'Pattern ID is required.', 'govalid-qr' ), array( 'status' => 400 ) );
		}

		$api    = new GoValid_QR_API();
		$result = $api->generate_numbering( $pattern_id, $quantity );

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

		return rest_ensure_response( $result );
	}

	/**
	 * Get signing PIN status.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_pin_status() {
		$client = new GoValid_API_Client();
		$result = $client->get( '/api/v1/account/mobile/pin/status/' );

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

		return rest_ensure_response( $result );
	}

	/**
	 * Verify signing PIN.
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response|WP_Error
	 */
	public function verify_pin( WP_REST_Request $request ) {
		$body = $request->get_json_params();
		$pin  = isset( $body['pin'] ) ? sanitize_text_field( $body['pin'] ) : '';

		if ( empty( $pin ) || strlen( $pin ) !== 6 ) {
			return new WP_Error( 'invalid_pin', __( 'Please enter a valid 6-digit PIN.', 'govalid-qr' ), array( 'status' => 400 ) );
		}

		$client = new GoValid_API_Client();
		$result = $client->post( '/api/v1/account/mobile/pin/verify/', array( 'pin' => $pin ) );

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

		return rest_ensure_response( $result );
	}

	/**
	 * Get existing anti-counterfeit tags.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_tags() {
		$client = new GoValid_API_Client();
		$result = $client->get( '/api/v1/anti-counterfeit/tags/' );

		if ( is_wp_error( $result ) ) {
			return rest_ensure_response( array( 'data' => array( 'tags' => array() ) ) );
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Get aggregate WordPress analytics.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_analytics() {
		$api    = new GoValid_QR_API();
		$result = $api->get_wp_analytics();

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

		return rest_ensure_response( $result );
	}

	/**
	 * Get analytics for a specific QR code.
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_qr_analytics( WP_REST_Request $request ) {
		$api    = new GoValid_QR_API();
		$result = $api->get_qr_analytics( $request->get_param( 'uuid' ) );

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

		return rest_ensure_response( $result );
	}

	/**
	 * Delete a QR code.
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response|WP_Error
	 */
	public function delete_qr_code( WP_REST_Request $request ) {
		$api    = new GoValid_QR_API();
		$result = $api->delete_qr_code( $request->get_param( 'uuid' ) );

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

		return rest_ensure_response( $result );
	}

	/**
	 * Proxy ad tracking to GoValid API (avoids CORS).
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function track_ad( WP_REST_Request $request ) {
		$ad_id  = absint( $request->get_param( 'ad_id' ) );
		$action = sanitize_key( $request->get_param( 'action' ) );

		if ( ! $ad_id || ! in_array( $action, array( 'impression', 'click' ), true ) ) {
			return rest_ensure_response( array( 'status' => 'ignored' ) );
		}

		$base_url = GoValid_QR::get_base_url();
		$url      = $base_url . '/api/v1/plugin/ads/track/';

		wp_remote_post( $url, array(
			'timeout'    => 3,
			'blocking'   => false,
			'user-agent' => 'GoValid-QR-WordPress/' . GOVALID_QR_VERSION,
			'headers'    => array(
				'Content-Type' => 'application/json',
				'Accept'       => 'application/json',
			),
			'body'       => wp_json_encode( array(
				'ad_id'  => $ad_id,
				'action' => $action,
			) ),
		) );

		return rest_ensure_response( array( 'status' => 'ok' ) );
	}

	/**
	 * Permission check: can edit posts.
	 *
	 * @return bool
	 */
	public function check_edit_permission(): bool {
		return current_user_can( 'edit_posts' );
	}
}
