<?php
/**
 * PeachPay PayPal functions.
 *
 * @phpcs:disable WordPress.Security.NonceVerification.Recommended
 *
 * @package PeachPay
 */

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

/**
 * Adds the feature flag for enabling stripe gateways.
 *
 * @param array $feature_list The list of features.
 */
function peachpay_paypal_register_feature( $feature_list ) {
	$feature_list['peachpay_paypal_gateways'] = array(
		'enabled'  => PeachPay_PayPal_Integration::connected() && PeachPay_PayPal_Integration::has_gateway_enabled(),
		'metadata' => array(
			'merchant_id'            => PeachPay_PayPal_Integration::merchant_id(),
			'client_id'              => PeachPay_PayPal_Integration::client_id(),
			'partner_attribution_id' => PeachPay_PayPal_Integration::partner_attribution_id(),
			'is_sandbox'             => peachpay_is_test_mode() || peachpay_is_local_development_site() || peachpay_is_staging_site(),

			'update_order_url'       => WC_AJAX::get_endpoint( 'pp-paypal-update-order' ),
			'update_order_security'  => wp_create_nonce( 'peachpay-paypal-update-order' ),

			'approve_order_url'      => WC_AJAX::get_endpoint( 'pp-paypal-approve-order' ),
		),
	);

	return $feature_list;
}

/**
 * WC Ajax request to update a PayPal order.
 */
function peachpay_paypal_handle_update_order() {
	if ( ! isset( $_POST['security'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['security'] ) ), 'peachpay-paypal-update-order' ) ) {
		return wp_send_json(
			array(
				'success' => false,
				'message' => 'Invalid nonce. Please refresh the page and try again.',
			),
			401
		);
	}

	if ( ! isset( $_POST['order_id'] ) ) {
		return wp_send_json(
			array(
				'success' => false,
				'message' => 'The field "order_id" is missing.',
			),
			400
		);
	}
	$order_id = absint( wp_unslash( $_POST['order_id'] ) );

	$order = wc_get_order( $order_id );
	if ( ! $order ) {
		return wp_send_json(
			array(
				'success' => false,
				'message' => 'The field "order_id" did not match any WooCommerce orders.',
			),
			404
		);
	}

	wp_send_json( PeachPay_PayPal::update_order( $order ) );
}

/**
 * WC Ajax request to capture a PayPal order.
 */
function peachpay_paypal_handle_approve_order() {
    // PHPCS:disable WordPress.Security.NonceVerification.Missing
	if ( ! isset( $_POST['order_id'] ) ) {
		return wp_send_json(
			array(
				'success' => false,
				'message' => 'The field "order_id" is missing.',
			),
			400
		);
	}

	$order_id = absint( wp_unslash( $_POST['order_id'] ) );
    // PHPCS:enable WordPress.Security.NonceVerification.Missing

	$order = wc_get_order( $order_id );
	if ( ! $order ) {
		return wp_send_json(
			array(
				'success' => false,
				'message' => 'The field "order_id" did not match any WooCommerce orders.',
			),
			404
		);
	}

	wp_send_json( PeachPay_PayPal::capture_order( $order ) );
}

/**
 * Display some PayPay transaction details for an order.
 *
 * @param WC_Order $order The given order to display information for.
 */
function peachpay_paypal_display_order_transaction_details( $order ) {
	if ( did_action( 'woocommerce_admin_order_data_after_billing_address' ) > 1 ) {
		return;
	}
	if ( ! PeachPay_PayPal_Integration::is_payment_gateway( $order->get_payment_method() ) ) {
		return;
	}

	$order_id = PeachPay_PayPal_Order_Data::get_order_transaction_details( $order, 'id' );
	if ( null !== $order_id ) {
		include PeachPay::get_plugin_path() . '/core/payments/paypal/admin/views/html-paypal-payment-info.php';
	}
}

/**
 * Displays the PayPal fee and net payout lines for the order dashboard.
 *
 * @param int $order_id Id for the order.
 */
function peachpay_paypal_display_fee_lines( $order_id ) {
	if ( did_action( 'woocommerce_admin_order_totals_after_total' ) > 1 ) {
		return;
	}

	$order    = wc_get_order( $order_id );
	$refunded = floatval( $order->get_total_refunded() );

	if ( ! PeachPay_PayPal_Integration::is_payment_gateway( $order->get_payment_method() ) || ( ! ( $order->is_paid() ) && 0 === $refunded ) ) {
		return;
	}

	$status = PeachPay_PayPal_Order_Data::get_order_transaction_details( $order, 'status' );
	if ( 'COMPLETED' === $status ) {
		include PeachPay::get_plugin_path() . '/core/payments/paypal/admin/views/html-paypal-transaction-fees.php';
	}
}

/**
 * Hides the WooCommerce admin refund UI for paid PeachPay PayPal orders.
 *
 * @param bool          $render_refunds Whether the refunds UI should be rendered.
 * @param int           $order_id       WooCommerce order id.
 * @param WC_Order|bool $order          WooCommerce order object.
 */
function peachpay_paypal_hide_admin_refund_button( $render_refunds, $order_id, $order ) {
	if ( ! $order ) {
		$order = wc_get_order( $order_id );
	}

	if ( ! $order || ! PeachPay_PayPal_Integration::is_payment_gateway( $order->get_payment_method() ) ) {
		return $render_refunds;
	}

	if ( $order->is_paid() ) {
		return false;
	}

	return $render_refunds;
}

/**
 * Callback function that gets activated when merchant changes order status to cancelled.
 *
 * @param string $order_id The order id of the order that was cancelled.
 */
function peachpay_paypal_handle_order_cancelled( $order_id ) {
	$order = wc_get_order( $order_id );

	if ( ! $order || ! PeachPay_PayPal_Integration::is_payment_gateway( $order->get_payment_method() ) ) {
		return;
	}

	if ( PeachPay_PayPal_Advanced::get_setting( 'refund_on_cancel' ) !== 'yes' ) {
		return;
	}

	if ( $order->get_transaction_id() && $order->get_total() > 0 ) {
		$refund_result = PeachPay_PayPal::refund_payment(
			$order,
			array(
				'amount'        => array(
					'currency_code' => $order->get_currency(),
					'value'         => $order->get_total(),
				),
				'note_to_payer' => 'Order was canceled or removed.',
			)
		);

		if ( ! $refund_result['success'] ) {
			return;
		}

		$refund = new WC_Order_Refund();
		$refund->set_amount( $order->get_total() - $order->get_total_refunded() );
		$refund->set_parent_id( $order->get_id() );
		$refund->set_reason( 'Order was canceled or removed.' );
		$refund->set_refunded_by( get_current_user_id() );
		$refund->save();

		$order->set_status( 'refunded' );
		$order->save();
	}
}

/**
 * Makes sure if a PayPal gateway is selected on checkout to auto hide the button so the "Place Order" is not shown for a brief amount of time.
 *
 * @param string $button The existing button html.
 */
function peachpay_paypal_custom_order_button_html( $button ) {
	if ( ! WC()->session ) {
		return $button;
	}

	$chosen_payment_method = WC()->session->get( 'chosen_payment_method' );
	if ( peachpay_starts_with( $chosen_payment_method, 'peachpay_paypal_' ) ) {
		return str_replace( '<button', '<button style="display:none;" ', $button );
	}

	return $button;
}

/**
 * Handles PayPal settings actions.
 */
function peachpay_paypal_handle_admin_actions() {
	if ( isset( $_GET['connected_paypal'] ) && 'true' === $_GET['connected_paypal'] ) {
		add_settings_error(
			'peachpay_messages',
			'peachpay_message',
			__( 'You have successfully connected your PayPal account. You may set up other payment methods in the "Payment methods" tab.', 'peachpay-for-woocommerce' ),
			'success'
		);
	}

	if ( isset( $_GET['unlink_paypal'] ) && PeachPay_PayPal_Integration::connected() ) {
		peachpay_unlink_paypal();
	}

	if ( isset( $_GET['unlink_paypal_manual'] ) && PeachPay_PayPal_Credentials::is_configured() ) {
		PeachPay_PayPal_Credentials::delete_credentials();
		add_settings_error(
			'peachpay_messages',
			'peachpay_message',
			__( 'PayPal credentials have been removed.', 'peachpay-for-woocommerce' ),
			'success'
		);
		wp_safe_redirect( admin_url( 'admin.php?page=peachpay&tab=payment#paypal' ) );
		exit;
	}
}

/**
 * Handle Paypal plugin capabilities.
 */
function peachpay_paypal_handle_plugin_capabilities() {
	// Update paypal capabilities and config info.
	if ( PeachPay_Capabilities::has( 'paypal', 'config' ) ) {
		update_option( 'peachpay_connected_paypal_config', PeachPay_Capabilities::get( 'paypal', 'config' ) );
	} else {
		delete_option( 'peachpay_connected_paypal_config' );
	}

	// Update paypal capabilities and account info.
	if ( PeachPay_Capabilities::has( 'paypal', 'account' ) ) {
		update_option( 'peachpay_connected_paypal_account', PeachPay_Capabilities::get( 'paypal', 'account' ) );
	} else {
		delete_option( 'peachpay_connected_paypal_account' );
	}
}

/**
 * Unlink merchant PayPal Account
 */
function peachpay_unlink_paypal() {
	if ( ! peachpay_unlink_paypal_request() ) {
		add_settings_error( 'peachpay_messages', 'peachpay_message', __( 'Unable to unlink PayPal account. Please try again or contact us if you need help.', 'peachpay-for-woocommerce' ), 'error' );
		return;
	}

	delete_option( 'peachpay_connected_paypal_account' );

	add_settings_error(
		'peachpay_messages',
		'peachpay_message',
		__( 'You have successfully unlinked your PayPal account. Please revoke the API permissions in your PayPal account settings as well.', 'peachpay-for-woocommerce' ),
		'success'
	);
}

/**
 * Get unlink merchant PayPal status.
 *
 * Unlink is local-only; no PeachPay server call.
 *
 * @return int 1 (success) so local options can be cleared.
 */
function peachpay_unlink_paypal_request() {
	return 1;
}

/**
 * Validates PayPal API credentials by requesting an OAuth2 token.
 *
 * @param string $client_id     PayPal Client ID.
 * @param string $client_secret PayPal Client Secret.
 * @return array{success: bool, message?: string}
 */
function peachpay_paypal_validate_credentials( $client_id, $client_secret ) {
	if ( empty( $client_id ) || empty( $client_secret ) ) {
		return array(
			'success' => false,
			'message' => __( 'Client ID and Client Secret are required.', 'peachpay-for-woocommerce' ),
		);
	}

	$base_url = peachpay_is_test_mode() ? 'https://api.sandbox.paypal.com' : 'https://api.paypal.com';
	$response = wp_remote_post(
		$base_url . '/v1/oauth2/token',
		array(
			'headers' => array(
				'Content-Type'  => 'application/x-www-form-urlencoded',
				'Authorization' => 'Basic ' . base64_encode( $client_id . ':' . $client_secret ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
			),
			'body'    => 'grant_type=client_credentials',
		)
	);

	if ( is_wp_error( $response ) ) {
		return array(
			'success' => false,
			'message' => $response->get_error_message(),
		);
	}

	$code = wp_remote_retrieve_response_code( $response );
	if ( 200 !== (int) $code ) {
		$body = json_decode( wp_remote_retrieve_body( $response ), true );
		$msg  = isset( $body['error_description'] ) ? $body['error_description'] : __( 'Invalid credentials. Please check your Client ID and Secret.', 'peachpay-for-woocommerce' );
		return array(
			'success' => false,
			'message' => $msg,
		);
	}

	return array( 'success' => true );
}

/**
 * AJAX handler to save PayPal manual credentials.
 */
function peachpay_paypal_ajax_save_credentials() {
	check_ajax_referer( 'peachpay_paypal_ajax_save', 'peachpay_paypal_ajax_nonce' );

	if ( ! current_user_can( 'manage_woocommerce' ) ) {
		wp_send_json_error( array( 'message' => __( 'Permission denied.', 'peachpay-for-woocommerce' ) ) );
	}

	$client_id     = isset( $_POST['paypal_client_id'] ) ? sanitize_text_field( wp_unslash( $_POST['paypal_client_id'] ) ) : '';
	$client_secret = isset( $_POST['paypal_client_secret'] ) ? wp_unslash( $_POST['paypal_client_secret'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

	$result = PeachPay_PayPal_Credentials::save_credentials(
		array(
			'client_id'     => $client_id,
			'client_secret' => $client_secret,
		)
	);

	if ( $result['success'] ) {
		wp_send_json_success( array( 'message' => $result['message'] ) );
	}

	wp_send_json_error( array( 'message' => $result['message'] ) );
}
