<?php
/**
 * HJCyberX Checkout for Paddle Lite Payment Gateway.
 *
 * Extends WC_Payment_Gateway to provide the Paddle Billing
 * overlay checkout experience inside WooCommerce.
 *
 * @package HJCyberX Checkout for Paddle Lite
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class PaddleKonnect_Lite_Gateway
 */
class PaddleKonnect_Lite_Gateway extends WC_Payment_Gateway {

	/**
	 * Constructor — sets up gateway ID, title, and form fields.
	 */
	public function __construct() {

		// ── Gateway identity ───────────────────.
		$this->id                 = 'hjcyberx-checkout-for-paddle-lite';
		$this->icon               = ''; // Optional: set a URL for a payment icon.
		$this->has_fields         = false;
		$this->method_title       = __( 'HJCyberX Checkout for Paddle Lite', 'hjcyberx-checkout-for-paddle-lite' );
		$this->method_description = __(
			'Accept payments securely via Paddle Billing. Supports one-time purchases and subscriptions with an overlay checkout powered by Paddle.js.',
			'hjcyberx-checkout-for-paddle-lite'
		);

		// Supported features.
		$this->supports = array( 'products' );

		// ── Load settings ──────────────────────.
		$this->init_form_fields();
		$this->init_settings();

		// ── Read settings into properties ──────.
		$this->title       = $this->get_option( 'title' );
		$this->description = $this->get_option( 'description' );
		$this->enabled     = $this->get_option( 'enabled' );

		// ── Save settings hook ─────────────────.
		add_action(
			'woocommerce_update_options_payment_gateways_' . $this->id,
			array( $this, 'process_admin_options' )
		);
	}

	// ──────────────────────────────────────────.
	// Settings Form Fields.
	// ──────────────────────────────────────────.

	/**
	 * Define the admin settings fields.
	 */
	public function init_form_fields(): void {

		$this->form_fields = array(

			// ── Enable / Disable ───────────────.
			'enabled'        => array(
				'title'   => __( 'Enable / Disable', 'hjcyberx-checkout-for-paddle-lite' ),
				'type'    => 'checkbox',
				'label'   => __( 'Enable HJCyberX Checkout for Paddle Lite Payment Gateway', 'hjcyberx-checkout-for-paddle-lite' ),
				'default' => 'no',
			),

			// ── Title ──────────────────────────.
			'title'          => array(
				'title'       => __( 'Title', 'hjcyberx-checkout-for-paddle-lite' ),
				'type'        => 'text',
				'description' => __( 'The payment method title the customer sees during checkout.', 'hjcyberx-checkout-for-paddle-lite' ),
				'default'     => __( 'Credit / Debit Card (Paddle)', 'hjcyberx-checkout-for-paddle-lite' ),
				'desc_tip'    => true,
			),

			// ── Description ────────────────────.
			'description'    => array(
				'title'       => __( 'Description', 'hjcyberx-checkout-for-paddle-lite' ),
				'type'        => 'textarea',
				'description' => __( 'Description shown to the customer on the checkout page.', 'hjcyberx-checkout-for-paddle-lite' ),
				'default'     => __( 'Pay securely using your credit or debit card via Paddle.', 'hjcyberx-checkout-for-paddle-lite' ),
				'desc_tip'    => true,
			),

			// ── Sandbox Mode ───────────────────.
			'sandbox_mode'   => array(
				'title'       => __( 'Sandbox Mode', 'hjcyberx-checkout-for-paddle-lite' ),
				'type'        => 'checkbox',
				'label'       => __( 'Enable Paddle Sandbox (test) environment', 'hjcyberx-checkout-for-paddle-lite' ),
				'description' => __( 'When enabled, all transactions go through the Paddle Sandbox. Use Sandbox credentials below.', 'hjcyberx-checkout-for-paddle-lite' ),
				'default'     => 'yes',
				'desc_tip'    => true,
			),

			// ── Seller ID ──────────────────────.
			'seller_id'      => array(
				'title'             => __( 'Paddle Seller ID', 'hjcyberx-checkout-for-paddle-lite' ),
				'type'              => 'text',
				'description'       => __( 'Your Paddle Vendor / Seller ID. Found in Paddle Dashboard → Developer Tools.', 'hjcyberx-checkout-for-paddle-lite' ),
				'default'           => '',
				'desc_tip'          => true,
				'placeholder'       => __( 'e.g. 12345', 'hjcyberx-checkout-for-paddle-lite' ),
				'custom_attributes' => array( 'autocomplete' => 'off' ),
			),

			// ── Client-Side Token ──────────────.
			'client_token'   => array(
				'title'             => __( 'Client-Side Token', 'hjcyberx-checkout-for-paddle-lite' ),
				'type'              => 'text',
				'description'       => __( 'Used to initialise Paddle.js on the frontend. Found in Paddle Dashboard → Developer Tools → Authentication.', 'hjcyberx-checkout-for-paddle-lite' ),
				'default'           => '',
				'desc_tip'          => true,
				'placeholder'       => __( 'test_...  or  live_...', 'hjcyberx-checkout-for-paddle-lite' ),
				'custom_attributes' => array( 'autocomplete' => 'off' ),
			),

			// ── API Key (server-side) ──────────.
			'api_key'        => array(
				'title'             => __( 'API Key', 'hjcyberx-checkout-for-paddle-lite' ),
				'type'              => 'password',
				'description'       => __( 'Server-side API key for Paddle API calls. Keep this secret.', 'hjcyberx-checkout-for-paddle-lite' ),
				'default'           => '',
				'desc_tip'          => true,
				'custom_attributes' => array( 'autocomplete' => 'new-password' ),
			),

			// ── Webhook Secret ─────────────────.
			'webhook_secret' => array(
				'title'             => __( 'Webhook Secret Key', 'hjcyberx-checkout-for-paddle-lite' ),
				'type'              => 'password',
				'description'       => sprintf(
					/* translators: %s: webhook URL */
					__( 'Used to verify inbound webhooks from Paddle. Set your Paddle notification destination URL to: %s', 'hjcyberx-checkout-for-paddle-lite' ),
					'<code>' . esc_url( rest_url( 'paddlekonnect/v1/webhook' ) ) . '</code>'
				),
				'default'           => '',
				'custom_attributes' => array( 'autocomplete' => 'new-password' ),
			),
		);
	}

	// ──────────────────────────────────────────.
	// Process Payment.
	// ──────────────────────────────────────────.

	/**
	 * Process the payment.
	 *
	 * In the HJCyberX Checkout for Paddle Lite flow the order is created first via AJAX,
	 * then the Paddle overlay is opened client-side. This method is a
	 * fallback in case WooCommerce calls it directly.
	 *
	 * @param  int $order_id WooCommerce order ID.
	 * @return array Result array with 'result' and 'redirect' keys.
	 */
	public function process_payment( $order_id ): array {

		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			wc_add_notice( __( 'Order not found. Please try again.', 'hjcyberx-checkout-for-paddle-lite' ), 'error' );
			return array( 'result' => 'failure' );
		}

		// Set the order to pending-payment. Paddle will confirm via webhook.
		$order->update_status( 'pending', __( 'Awaiting Paddle payment.', 'hjcyberx-checkout-for-paddle-lite' ) );
		$order->update_meta_data( '_paddlekonnect_pending', 'yes' );
		$order->save();

		try {
			// Build items for Paddle.
			$paddle_items = array();
			$is_sandbox   = $this->get_option( 'sandbox_mode' ) === 'yes';
			$price_id_key = $is_sandbox ? '_paddlekonnect_sandbox_price_id' : '_paddlekonnect_price_id';

			foreach ( $order->get_items() as $item ) {
				$product = $item->get_product();

				// If product was deleted or doesn't exist, skip it.
				if ( ! $product ) {
					continue;
				}

				$price_id = get_post_meta( $product->get_id(), $price_id_key, true );

				if ( ! empty( $price_id ) ) {
					// Predefined price required in Lite version.
					$paddle_items[] = array(
						'price_id' => $price_id,
						'quantity' => $item->get_quantity(),
					);
				} else {
					// Throw an error enforcing upgrade to Pro for auto-fetch and dynamic pricing.
					throw new \Exception(
						sprintf(
						/* translators: %s: product name */
							__( 'Please enter a Paddle Price ID for the product "%s", or upgrade to HJCyberX Checkout for Paddle Pro to enable Auto-Fetch and dynamic discount support.', 'hjcyberx-checkout-for-paddle-lite' ),
							$product->get_name()
						)
					);
				}
			}

			// Call Paddle API.
			$api_url = $is_sandbox ? 'https://sandbox-api.paddle.com/transactions' : 'https://api.paddle.com/transactions';
			$api_key = $this->get_option( 'api_key' );

			if ( empty( $api_key ) ) {
				throw new \Exception( __( 'Paddle API key is not configured.', 'hjcyberx-checkout-for-paddle-lite' ) );
			}

			$payload = array(
				'items'       => $paddle_items,
				'custom_data' => array(
					'wc_order_id'  => (string) $order_id,
					'wc_order_key' => $order->get_order_key(),
					'return_url'   => $this->get_return_url( $order ),
				),
			);

			$response = wp_remote_post(
				$api_url,
				array(
					'headers' => array(
						'Authorization' => 'Bearer ' . $api_key,
						'Content-Type'  => 'application/json',
					),
					'body'    => wp_json_encode( $payload ),
					'timeout' => 15,
				)
			);

			if ( is_wp_error( $response ) ) {
				throw new \Exception( 'Failed to connect to Paddle API: ' . $response->get_error_message() );
			}

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

			if ( empty( $body['data']['id'] ) ) {
				$error_msg = isset( $body['error']['detail'] ) ? $body['error']['detail'] : 'Unknown Paddle API error.';
				if ( isset( $body['error']['errors'] ) && is_array( $body['error']['errors'] ) ) {
					foreach ( $body['error']['errors'] as $err ) {
						$error_msg .= ' ' . ( $err['message'] ?? '' );
					}
				}
				throw new \Exception( 'Paddle API Error: ' . $error_msg );
			}

			$transaction_id = sanitize_text_field( $body['data']['id'] );

			PaddleKonnect_Lite_Logger::info( sprintf( 'Order #%d pending. Paddle Txn: %s', $order_id, $transaction_id ) );

			// Return success and use a hash fragment to pass the transaction ID to the frontend JS.
			return array(
				'result'   => 'success',
				'redirect' => '#paddlekonnect-' . $transaction_id,
			);

		} catch ( \Throwable $e ) {
			PaddleKonnect_Lite_Logger::error( 'Order creation failed: ' . $e->getMessage() );
			wc_add_notice( $e->getMessage(), 'error' );
			return array( 'result' => 'failure' );
		}
	}
}
