<?php
/**
 * Equalza_Billing_REST — REST API endpoints for billing/subscriptions.
 *
 * Endpoints: checkout, subscription, invoices, cancel, reactivate, webhook.
 */
defined( 'ABSPATH' ) || exit;

class Equalza_Billing_REST {

	private const NS = 'equalza/v1';

	/** Rate limits */
	private const RATE_CHECKOUT = [ 'limit' => 20, 'window' => 3600 ];
	private const RATE_CANCEL   = [ 'limit' => 3,  'window' => 3600 ];
	private const RATE_DEFAULT  = [ 'limit' => 30, 'window' => 60 ];

	public static function init(): void {
		add_action( 'rest_api_init', [ __CLASS__, 'register_routes' ] );
	}

	public static function register_routes(): void {
		// Create checkout session → returns payment URL.
		register_rest_route( self::NS, '/billing/checkout', [
			'methods'             => 'POST',
			'callback'            => [ __CLASS__, 'handle_checkout' ],
			'permission_callback' => [ __CLASS__, 'require_login' ],
			'args'                => [
				'plan' => [
					'required' => true,
					'type'     => 'string',
					'enum'     => [ 'pro_monthly', 'pro_annual' ],
				],
			],
		] );

		// Get current subscription.
		register_rest_route( self::NS, '/billing/subscription', [
			'methods'             => 'GET',
			'callback'            => [ __CLASS__, 'handle_get_subscription' ],
			'permission_callback' => [ __CLASS__, 'require_login' ],
		] );

		// Get payment history.
		register_rest_route( self::NS, '/billing/invoices', [
			'methods'             => 'GET',
			'callback'            => [ __CLASS__, 'handle_get_invoices' ],
			'permission_callback' => [ __CLASS__, 'require_login' ],
		] );

		// Cancel subscription.
		register_rest_route( self::NS, '/billing/cancel', [
			'methods'             => 'POST',
			'callback'            => [ __CLASS__, 'handle_cancel' ],
			'permission_callback' => [ __CLASS__, 'require_login' ],
		] );

		// Reactivate subscription.
		register_rest_route( self::NS, '/billing/reactivate', [
			'methods'             => 'POST',
			'callback'            => [ __CLASS__, 'handle_reactivate' ],
			'permission_callback' => [ __CLASS__, 'require_login' ],
		] );

		// Green Invoice webhook (public, verified by HMAC).
		register_rest_route( self::NS, '/billing/webhook', [
			'methods'             => 'POST',
			'callback'            => [ __CLASS__, 'handle_webhook' ],
			'permission_callback' => '__return_true',
		] );

	}

	/* ── Handlers ──────────────────────────────────────────────────────── */

	public static function handle_checkout( \WP_REST_Request $request ): \WP_REST_Response {
		$limited = self::check_rate_limit( 'checkout', self::RATE_CHECKOUT );
		if ( $limited ) {
			return $limited;
		}

		$plan    = sanitize_text_field( $request->get_param( 'plan' ) );
		$user_id = get_current_user_id();

		$result = Equalza_Billing::create_checkout( $user_id, $plan );

		if ( ! $result['success'] ) {
			return new \WP_REST_Response( $result, 400 );
		}

		return new \WP_REST_Response( $result, 200 );
	}

	public static function handle_get_subscription( \WP_REST_Request $request ): \WP_REST_Response {
		$user_id = get_current_user_id();
		$sub     = Equalza_Billing::get_subscription( $user_id );

		if ( ! $sub ) {
			return new \WP_REST_Response( [
				'success' => true,
				'plan'    => 'free',
				'status'  => 'none',
			], 200 );
		}

		return new \WP_REST_Response( [
			'success'              => true,
			'plan'                 => $sub['plan'],
			'status'               => $sub['status'],
			'price_cents'          => (int) $sub['price_cents'],
			'currency'             => $sub['currency'],
			'current_period_start' => $sub['current_period_start'],
			'current_period_end'   => $sub['current_period_end'],
			'cancelled_at'         => $sub['cancelled_at'],
			'created_at'           => $sub['created_at'],
		], 200 );
	}

	public static function handle_get_invoices( \WP_REST_Request $request ): \WP_REST_Response {
		$user_id  = get_current_user_id();
		$payments = Equalza_Billing::get_payments( $user_id );

		$items = array_map( function ( $p ) {
			return [
				'id'          => (int) $p['id'],
				'type'        => $p['type'],
				'amount'      => Equalza_Billing::format_amount( (int) $p['amount_cents'], $p['currency'] ),
				'amount_cents'=> (int) $p['amount_cents'],
				'status'      => $p['status'],
				'invoice_url' => $p['invoice_url'],
				'description' => $p['description'],
				'date'        => $p['created_at'],
			];
		}, $payments );

		return new \WP_REST_Response( [
			'success'  => true,
			'invoices' => $items,
		], 200 );
	}

	public static function handle_cancel( \WP_REST_Request $request ): \WP_REST_Response {
		$limited = self::check_rate_limit( 'cancel', self::RATE_CANCEL );
		if ( $limited ) {
			return $limited;
		}

		$result = Equalza_Billing::cancel_subscription( get_current_user_id() );

		return new \WP_REST_Response( $result, $result['success'] ? 200 : 400 );
	}

	public static function handle_reactivate( \WP_REST_Request $request ): \WP_REST_Response {
		$result = Equalza_Billing::reactivate_subscription( get_current_user_id() );

		return new \WP_REST_Response( $result, $result['success'] ? 200 : 400 );
	}

	/* ── Webhook ───────────────────────────────────────────────────────── */

	public static function handle_webhook( \WP_REST_Request $request ): \WP_REST_Response {
		$raw_body  = $request->get_body();
		$secret    = get_option( 'equalza_gi_webhook_secret', '' );

		// Verify signature if secret is configured.
		if ( ! empty( $secret ) ) {
			$signature = $request->get_header( 'X-GreenInvoice-Signature' )
			           ?: $request->get_header( 'X-GI-Signature' )
			           ?: '';

			if ( empty( $signature ) ) {
				error_log( '[equalza-billing] webhook_error: missing signature header.' );
				return new \WP_REST_Response( [ 'error' => 'missing_signature' ], 401 );
			}

			$expected = hash_hmac( 'sha256', $raw_body, $secret );
			if ( ! hash_equals( $expected, $signature ) ) {
				error_log( '[equalza-billing] webhook_error: invalid signature.' );
				return new \WP_REST_Response( [ 'error' => 'invalid_signature' ], 403 );
			}
		}

		$payload = json_decode( $raw_body, true );
		if ( ! $payload ) {
			return new \WP_REST_Response( [ 'error' => 'invalid_json' ], 400 );
		}

		$event = $payload['event'] ?? ( $payload['type'] ?? '' );

		switch ( $event ) {
			case 'payment/received':
				Equalza_Billing::process_payment_received( $payload );
				break;

			case 'sale-pages/order-paid':
				Equalza_Billing::process_order_paid( $payload );
				break;

			default:
				error_log( '[equalza-billing] webhook_unknown_event: ' . sanitize_key( $event ) );
		}

		return new \WP_REST_Response( [ 'ok' => true ], 200 );
	}

	/* ── Helpers ───────────────────────────────────────────────────────── */

	public static function require_login(): bool {
		return is_user_logged_in();
	}

	private static function check_rate_limit( string $action, array $config ): ?\WP_REST_Response {
		$ip  = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0' ) );
		$key = 'eq_bill_rate_' . substr( md5( $ip . $action ), 0, 16 );
		$cur = (int) get_transient( $key );

		if ( $cur >= $config['limit'] ) {
			return new \WP_REST_Response( [ 'success' => false, 'code' => 'rate_limited' ], 429 );
		}

		set_transient( $key, $cur + 1, $config['window'] );
		return null;
	}

}
