<?php
/**
 * Wayl Webhook Handler
 *
 * Handles incoming webhook requests from Wayl payment gateway.
 *
 * @package Wayl_Checkout
 * @since 1.2.0
 */

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

/**
 * Class WaylCHP_Webhook_Handler
 */
class WaylCHP_Webhook_Handler {

	/**
	 * Initialize webhook handler
	 *
	 * @return void
	 */
	public static function init() {
		add_action( 'init', array( self::class, 'maybe_handle_webhook' ) );
	}

	/**
	 * Check if this is a webhook request and handle it
	 *
	 * @return void
	 */
	public static function maybe_handle_webhook() {
		// Sanitize and validate GET parameter
		// Note: Nonce verification is not applicable here as this is a webhook endpoint
		// called by external service (Wayl), not user-submitted form data
		$wc_api = isset( $_GET['wc-api'] ) ? sanitize_text_field( wp_unslash( $_GET['wc-api'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		if ( $wc_api === 'waylchp_webhook' ) {
			self::handle_webhook();
			exit;
		}
	}

	/**
	 * Handle incoming webhook request
	 *
	 * @return void
	 */
	public static function handle_webhook() {
		// Initialize logger
		WaylCHP_Logger::init();

		WaylCHP_Logger::info( 'Wayl webhook received' );

		// Only accept POST requests
		$request_method = '';
		if ( isset( $_SERVER['REQUEST_METHOD'] ) && is_string( $_SERVER['REQUEST_METHOD'] ) ) {
			$request_method = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) );
		}
		if ( $request_method !== 'POST' ) {
			WaylCHP_Logger::warning( 'Webhook received with non-POST method: ' . $request_method );
			status_header( 405 );
			wp_send_json_error( array( 'message' => 'Method Not Allowed' ), 405 );
			exit;
		}

		// Get raw body using WordPress method
		$raw_body = file_get_contents( 'php://input' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents

		if ( empty( $raw_body ) ) {
			WaylCHP_Logger::error( 'Webhook received with empty body' );
			status_header( 400 );
			wp_send_json_error( array( 'message' => 'Empty Payload' ), 400 );
			exit;
		}

		// Verify webhook signature if provided
		$webhook_secret = get_option( 'waylchp_webhook_secret' );
		if ( ! empty( $webhook_secret ) ) {
			$signature_header = '';
			if ( isset( $_SERVER['HTTP_X_WAYL_SIGNATURE'] ) && is_string( $_SERVER['HTTP_X_WAYL_SIGNATURE'] ) ) {
				$signature_header = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_WAYL_SIGNATURE'] ) );
			}

			if ( ! empty( $signature_header ) ) {
				if ( ! WaylCHP_API::verify_webhook_signature( $raw_body, $signature_header, $webhook_secret ) ) {
					WaylCHP_Logger::error( 'Webhook signature verification failed' );
					status_header( 401 );
					wp_send_json_error( array( 'message' => 'Invalid Signature' ), 401 );
					exit;
				}
				WaylCHP_Logger::info( 'Webhook signature verified successfully' );
			} else {
				WaylCHP_Logger::warning( 'No webhook signature provided' );
			}
		}

		$data = json_decode( $raw_body, true );

		if ( json_last_error() !== JSON_ERROR_NONE || ! $data || ! is_array( $data ) ) {
			WaylCHP_Logger::error( 'Failed to decode webhook JSON payload: ' . json_last_error_msg() );
			status_header( 400 );
			wp_send_json_error( array( 'message' => 'Invalid JSON' ), 400 );
			exit;
		}

		WaylCHP_Logger::info( 'Webhook payload decoded: ' . wp_json_encode( $data ) );

		// Validate required fields
		if ( ! isset( $data['referenceId'], $data['paymentStatus'] ) ) {
			WaylCHP_Logger::error( 'Webhook missing required fields: referenceId or paymentStatus' );
			status_header( 400 );
			wp_send_json_error( array( 'message' => 'Missing Required Fields' ), 400 );
			exit;
		}

		$reference_id   = isset( $data['referenceId'] ) ? sanitize_text_field( $data['referenceId'] ) : '';
		$payment_status = isset( $data['paymentStatus'] ) ? sanitize_text_field( $data['paymentStatus'] ) : '';

		WaylCHP_Logger::info( "Processing webhook - Reference ID: $reference_id, Status: $payment_status" );

		// Process only if paymentStatus is "Paid"
		if ( $payment_status !== 'Paid' ) {
			WaylCHP_Logger::info( "Ignoring webhook with status: $payment_status" );
			status_header( 200 );
			echo 'Ignored - Not Paid';
			exit;
		}

		// Store reference ID in order meta for refunds
		// Extract WC order ID from referenceId (format: waylchp_ORDERID_TIMESTAMP)
		if ( ! preg_match( '/^waylchp_(\d+)_\d+$/', $reference_id, $matches ) ) {
			WaylCHP_Logger::error( 'Invalid reference ID format: ' . $reference_id );
			status_header( 400 );
			wp_send_json_error( array( 'message' => 'Invalid Reference ID Format' ), 400 );
			exit;
		}

		$order_id = isset( $matches[1] ) ? absint( $matches[1] ) : 0;

		if ( $order_id <= 0 ) {
			WaylCHP_Logger::error( 'Invalid order ID extracted from reference: ' . $reference_id );
			status_header( 400 );
			wp_send_json_error( array( 'message' => 'Invalid Order ID' ), 400 );
			exit;
		}

		$order = wc_get_order( $order_id );

		if ( ! $order || ! is_a( $order, 'WC_Order' ) ) {
			WaylCHP_Logger::error( 'Order not found for ID: ' . $order_id );
			status_header( 404 );
			wp_send_json_error( array( 'message' => 'Order Not Found' ), 404 );
			exit;
		}

		// Store reference ID in order meta for refunds
		$order->update_meta_data( 'waylchp_reference_id', sanitize_text_field( $reference_id ) );

		WaylCHP_Logger::info( "Processing payment for order: $order_id (Status: " . $order->get_status() . ')' );

		// Check if order is already processed
		$current_status = $order->get_status();
		if ( $current_status !== 'pending' && $current_status !== 'on-hold' ) {
			WaylCHP_Logger::info( 'Order ' . $order_id . ' already processed (Status: ' . $current_status . ')' );
			status_header( 200 );
			wp_send_json_success( array( 'message' => 'Order Already Processed' ) );
			exit;
		}

		try {
			// Extract additional payment details from webhook
			$payment_details = array();

			// Payment status
			if ( isset( $data['paymentStatus'] ) ) {
				$payment_details['paymentStatus'] = sanitize_text_field( $data['paymentStatus'] );
			}

			// Payment method
			if ( isset( $data['paymentMethod'] ) ) {
				$payment_details['paymentMethod'] = sanitize_text_field( $data['paymentMethod'] );
			}

			// Payment processor
			if ( isset( $data['paymentProcessor'] ) ) {
				$payment_details['paymentProcessor'] = sanitize_text_field( $data['paymentProcessor'] );
			}

			// Total amount
			if ( isset( $data['total'] ) ) {
				$payment_details['total'] = sanitize_text_field( $data['total'] );
			}

			// Customer details
			if ( isset( $data['customer'] ) && is_array( $data['customer'] ) ) {
				if ( isset( $data['customer']['name'] ) ) {
					$payment_details['customerName'] = sanitize_text_field( $data['customer']['name'] );
				}
				if ( isset( $data['customer']['phone'] ) ) {
					$payment_details['customerPhone'] = sanitize_text_field( $data['customer']['phone'] );
				}
			}

			// Log the extracted payment details
			if ( ! empty( $payment_details ) ) {
				WaylCHP_Logger::info( 'Extracted payment details: ' . wp_json_encode( $payment_details ) );
			}

			// Store payment details as order meta with proper sanitization
			foreach ( $payment_details as $key => $value ) {
				$meta_key   = 'waylchp_' . sanitize_key( $key );
				$meta_value = is_string( $value ) ? sanitize_text_field( $value ) : $value;
				$order->update_meta_data( $meta_key, $meta_value );
			}

			// Complete the payment
			$order->payment_complete();

			// Add comprehensive order note with payment details
			$order_note = esc_html__( 'Payment confirmed via Wayl webhook at', 'wayl-checkout' ) . ' ' . current_time( 'mysql' );

			if ( ! empty( $payment_details ) ) {
				$order_note .= "\n\n" . esc_html__( 'Payment Details:', 'wayl-checkout' );
				if ( isset( $payment_details['paymentStatus'] ) ) {
					$order_note .= "\n- " . esc_html__( 'Status:', 'wayl-checkout' ) . ' ' . esc_html( $payment_details['paymentStatus'] );
				}
				if ( isset( $payment_details['paymentMethod'] ) ) {
					$order_note .= "\n- " . esc_html__( 'Method:', 'wayl-checkout' ) . ' ' . esc_html( $payment_details['paymentMethod'] );
				}
				if ( isset( $payment_details['paymentProcessor'] ) ) {
					$order_note .= "\n- " . esc_html__( 'Processor:', 'wayl-checkout' ) . ' ' . esc_html( $payment_details['paymentProcessor'] );
				}
				if ( isset( $payment_details['total'] ) ) {
					$order_note .= "\n- " . esc_html__( 'Total:', 'wayl-checkout' ) . ' ' . esc_html( $payment_details['total'] );
				}
				if ( isset( $payment_details['customerName'] ) ) {
					$order_note .= "\n- " . esc_html__( 'Customer:', 'wayl-checkout' ) . ' ' . esc_html( $payment_details['customerName'] );
				}
				if ( isset( $payment_details['customerPhone'] ) ) {
					$order_note .= "\n- " . esc_html__( 'Phone:', 'wayl-checkout' ) . ' ' . esc_html( $payment_details['customerPhone'] );
				}
			}

			$order->add_order_note( $order_note );

			// Update customer information if available
			if ( isset( $payment_details['customerName'] ) && ! empty( $payment_details['customerName'] ) ) {
				$order->set_billing_first_name( sanitize_text_field( $payment_details['customerName'] ) );
			}

			if ( isset( $payment_details['customerPhone'] ) && ! empty( $payment_details['customerPhone'] ) ) {
				$order->set_billing_phone( sanitize_text_field( $payment_details['customerPhone'] ) );
			}

			// Save order once with all updates
			$order->save();

			WaylCHP_Logger::info( 'Payment completed successfully for order: ' . $order_id );

			// Clear any cached data
			wp_cache_delete( $order_id, 'posts' );
			wc_delete_shop_order_transients( $order_id );

		} catch ( Exception $e ) {
			WaylCHP_Logger::error( 'Error completing payment for order ' . $order_id . ': ' . $e->getMessage() );
			status_header( 500 );
			wp_send_json_error( array( 'message' => 'Payment Processing Error' ), 500 );
			exit;
		}

		status_header( 200 );
		wp_send_json_success( array( 'message' => 'OK' ) );
		exit;
	}
}

