<?php
defined( 'ABSPATH' ) || exit;

class WCP_Gateway_Cashfree implements WCP_Payment_Gateway_Interface {

	private function config(): array {
		$s = get_option( 'woocom_pay_settings', [] );
		return $s['gateways']['cashfree'] ?? [];
	}

	public function get_id(): string {
		return 'cashfree';
	}

	public function get_label(): string {
		return __( 'Cashfree (Cards · UPI · NetBanking · Wallets)', 'woocom-pay' );
	}

	public function is_enabled(): bool {
		return ! empty( $this->config()['enabled'] );
	}

	public function is_configured(): bool {
		$c = $this->config();
		return ! empty( $c['app_id'] ) && ! empty( $c['secret_key'] );
	}

	private function api_base(): string {
		$c = $this->config();
		return ! empty( $c['test_mode'] )
			? 'https://sandbox.cashfree.com/pg'
			: 'https://api.cashfree.com/pg';
	}

	// -------------------------------------------------------------------------

	public function create_payment( WC_Order $order, float $amount, string $return_url ): string|WP_Error {
		$config  = $this->config();
		$link_id = 'wcp_' . $order->get_id() . '_' . time();

		$payload = [
			'link_id'          => $link_id,
			'link_amount'      => round( $amount, 2 ),
			'link_currency'    => 'INR',
			'link_purpose'     => sprintf( __( 'Order #%s', 'woocom-pay' ), $order->get_order_number() ),
			'customer_details' => [
				'customer_name'  => trim( $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() ),
				'customer_email' => $order->get_billing_email(),
				'customer_phone' => preg_replace( '/[^0-9]/', '', $order->get_billing_phone() ) ?: '9999999999',
			],
			'link_notify'      => [ 'send_sms' => true, 'send_email' => true ],
			'link_meta'        => [
				'notify_url' => home_url( '/?wc-api=woocom_pay_cashfree_webhook' ),
				'return_url' => $return_url . ( strpos( $return_url, '?' ) !== false ? '&' : '?' ) . 'link_id={link_id}',
			],
		];

		$response = wp_remote_post(
			$this->api_base() . '/links',
			[
				'headers' => [
					'x-api-version'   => '2023-08-01',
					'x-client-id'     => $config['app_id'],
					'x-client-secret' => $config['secret_key'],
					'Content-Type'    => 'application/json',
				],
				'body'    => wp_json_encode( $payload ),
				'timeout' => 30,
			]
		);

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

		$code = wp_remote_retrieve_response_code( $response );
		$body = json_decode( wp_remote_retrieve_body( $response ), true );

		if ( $code !== 200 || empty( $body['link_url'] ) ) {
			$msg = $body['message'] ?? __( 'Cashfree: could not create payment link.', 'woocom-pay' );
			return new WP_Error( 'cashfree_error', $msg );
		}

		$order->update_meta_data( '_wcp_cashfree_link_id', $link_id );
		$order->save();

		return $body['link_url'];
	}

	// -------------------------------------------------------------------------
	// Return handler (WC API hook: woocommerce_api_woocom_pay_cashfree)
	// -------------------------------------------------------------------------

	public static function handle_return(): void {
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		$order_id   = (int) ( $_GET['order_id'] ?? 0 );
		$link_id    = sanitize_text_field( $_GET['link_id'] ?? '' );
		$is_balance = ! empty( $_GET['balance'] );
		// phpcs:enable WordPress.Security.NonceVerification.Recommended

		$order = $order_id ? wc_get_order( $order_id ) : null;
		if ( ! $order ) {
			wp_die( esc_html__( 'Order not found.', 'woocom-pay' ) );
		}

		if ( empty( $link_id ) ) {
			wc_add_notice( __( 'Payment was not completed. Please try again.', 'woocom-pay' ), 'error' );
			wp_safe_redirect( wc_get_checkout_url() );
			exit;
		}

		// Fetch the Cashfree payment link status to verify payment.
		$config   = ( new self() )->config();
		$base_url = ( new self() )->api_base();

		$response = wp_remote_get(
			$base_url . '/links/' . rawurlencode( $link_id ),
			[
				'headers' => [
					'x-api-version'   => '2023-08-01',
					'x-client-id'     => $config['app_id'],
					'x-client-secret' => $config['secret_key'],
				],
				'timeout' => 20,
			]
		);

		if ( is_wp_error( $response ) ) {
			wp_die( esc_html__( 'Could not verify payment status. Please contact support.', 'woocom-pay' ) );
		}

		$body   = json_decode( wp_remote_retrieve_body( $response ), true );
		$status = strtolower( $body['link_status'] ?? '' );

		if ( $status !== 'paid' ) {
			wc_add_notice( __( 'Payment was not completed. Please try again.', 'woocom-pay' ), 'error' );
			wp_safe_redirect( wc_get_checkout_url() );
			exit;
		}

		// Use the first payment's CF order ID as transaction ID.
		$payment_id = $body['link_orders'][0]['order_id'] ?? $link_id;

		self::complete_payment( $order, (string) $payment_id, 'Cashfree', $is_balance );

		wp_safe_redirect( $order->get_checkout_order_received_url() );
		exit;
	}

	// -------------------------------------------------------------------------
	// Webhook handler (WC API hook: woocommerce_api_woocom_pay_cashfree_webhook)
	// -------------------------------------------------------------------------

	public static function handle_webhook(): void {
		$raw_body  = file_get_contents( 'php://input' );
		$payload   = json_decode( $raw_body, true );
		$event     = $payload['data']['payment']['payment_status'] ?? '';
		$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
		$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

		$config         = get_option( 'woocom_pay_settings', [] );
		$webhook_secret = $config['gateways']['cashfree']['secret_key'] ?? '';

		if ( $webhook_secret && $signature && $timestamp ) {
			$expected = hash_hmac( 'sha256', $timestamp . $raw_body, $webhook_secret );
			if ( ! hash_equals( $expected, $signature ) ) {
				status_header( 400 );
				wp_die( 'Invalid signature.' );
			}
		}

		if ( strtoupper( $event ) === 'SUCCESS' ) {
			$link_id  = $payload['data']['payment']['cf_payment_id'] ?? '';
			$order_id = 0;

			// Extract WC order ID from link_id meta saved earlier (wcp_{order_id}_{ts}).
			if ( preg_match( '/^wcp_(\d+)_/', (string) $payload['data']['order']['order_id'], $m ) ) {
				$order_id = (int) $m[1];
			}

			$order = $order_id ? wc_get_order( $order_id ) : null;
			if ( $order ) {
				$is_balance = ( $order->get_status() === 'wc-bal-pending' );
				self::complete_payment( $order, (string) $link_id, 'Cashfree', $is_balance );
			}
		}

		status_header( 200 );
		echo 'OK';
		exit;
	}

	// -------------------------------------------------------------------------
	// Shared completion (delegates to Razorpay's static for code reuse)
	// -------------------------------------------------------------------------

	public static function complete_payment( WC_Order $order, string $payment_id, string $gateway_label, bool $is_balance ): void {
		WCP_Gateway_Razorpay::complete_payment( $order, $payment_id, $gateway_label, $is_balance );
	}
}
