<?php
/**
 * AnyCoin WooCommerce Payment Gateway.
 *
 * @package AnyCoin_Payment_Gateway
 */

defined( 'ABSPATH' ) || exit;

/**
 * WooCommerce AnyCoin Payment Gateway
 *
 * Provides an AnyCoin Payment Gateway for WooCommerce.
 */
class AnyCoin_Payment_Gateway extends WC_Payment_Gateway {

		/**
		 * API Instance
		 *
		 * @var AnyCoin_API
		 */
	private $api;

	/**
	 * Wallet address
	 *
	 * @var string
	 */
	public $wallet_address;

	/**
	 * View key
	 *
	 * @var string
	 */
	public $view_key;

	/**
	 * Price buffer
	 *
	 * @var float
	 */
	public $price_buffer;

	/**
	 * Required confirmations
	 *
	 * @var int
	 */
	public $confirmations;

	/**
	 * API URL
	 *
	 * @var string
	 */
	public $api_url;

	/**
	 * Payment ID Verification API URL
	 *
	 * @var string
	 */
	public $payment_id_api_url;

	/**
	 * Debug mode
	 *
	 * @var bool
	 */
	public $debug;

	/**
	 * Test mode
	 *
	 * @var bool
	 */
	public $test_mode;

	/**
	 * Constructor for the gateway.
	 */
	public function __construct() {
				$this->id           = 'anycoin_payment';
		$this->icon                 = ANYCOIN_PAYMENT_PLUGIN_URL . 'assets/images/anycoin/icon-blue.png';
		$this->has_fields           = false;
				$this->method_title = 'AnyCoin Payment';
		$this->method_description   = 'Accept cryptocurrency payments directly to your wallet with AnyCoin.';
		$this->supports             = [ 'products' ];

		$this->init_form_fields();
		$this->init_settings();

		$this->title              = 'AnyCoin Payment';
		$this->description        = $this->get_option( 'description' );
		$this->enabled            = $this->get_option( 'enabled' );
		$this->wallet_address     = $this->get_option( 'wallet_address' );
		$this->view_key           = $this->get_option( 'view_key' );
		$this->price_buffer       = $this->get_option( 'price_buffer' );
		$this->confirmations      = $this->get_option( 'confirmations' );
		$this->api_url            = $this->get_option( 'api_url' );
		$this->payment_id_api_url = $this->get_option( 'payment_id_api_url' );
		$this->debug              = 'yes' === $this->get_option( 'debug' );
		$this->test_mode          = 'yes' === $this->get_option( 'test_mode' );

		if ( ! defined( 'ANYCOIN_TEST_MODE' ) ) {
			define( 'ANYCOIN_TEST_MODE', $this->test_mode );
		}

		$api_config = [
			'api_url'            => $this->api_url,
			'wallet_address'     => $this->wallet_address,
			'view_key'           => $this->view_key,
			'payment_id_api_url' => $this->payment_id_api_url,
			'debug'              => $this->debug,
		];

				$this->api = new AnyCoin_API( $api_config );

		add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, [ $this, 'process_admin_options' ] );
		add_action( 'woocommerce_thankyou_' . $this->id, [ $this, 'thankyou_page' ] );
		add_action( 'woocommerce_email_before_order_table', [ $this, 'email_instructions' ], 10, 3 );
	}

	/**
	 * Initialize Gateway Settings Form Fields.
	 */
	public function init_form_fields() {
		$this->form_fields = [
			'enabled'            => [
				'title'   => 'Enable/Disable',
				'type'    => 'checkbox',
				'label'   => 'Enable AnyCoin Payment',
				'default' => 'no',
			],
			'test_mode'          => [
				'title'       => 'Test Mode',
				'type'        => 'checkbox',
				'label'       => 'Enable test mode',
				'description' => 'Test mode uses simulated transactions for testing. No real cryptocurrency will be transferred.',
				'default'     => 'yes',
			],
			'description'        => [
				'title'       => 'Description',
				'type'        => 'textarea',
				'description' => 'This controls the description which the user sees during checkout.',
				'default'     => 'Pay with cryptocurrency. Payments are processed instantly and securely with AnyCoin.',
				'desc_tip'    => true,
			],
			'wallet_address'     => [
				'title'       => 'Wallet Address',
				'type'        => 'text',
				'description' => 'Your cryptocurrency wallet address where payments will be sent. This is your public address that starts with "Zx".',
				'default'     => '',
				'desc_tip'    => true,
			],
			'view_key'           => [
				'title'       => 'Private View Key',
				'type'        => 'password',
				'description' => 'Your wallet private view key (for monitoring incoming transactions). This allows checking payments but not spending funds. Can be obtained from your wallet settings.',
				'default'     => '',
				'desc_tip'    => true,
			],
			'price_buffer'       => [
				'title'             => 'Price Buffer (%)',
				'type'              => 'number',
				'description'       => 'Additional percentage to add to the converted cryptocurrency amount to account for price fluctuations (e.g., 1 = add 1%).',
				'default'           => '1',
				'desc_tip'          => true,
				'custom_attributes' => [
					'min'  => '0',
					'max'  => '10',
					'step' => '0.1',
				],
			],
			'confirmations'      => [
				'title'       => 'Required Confirmations',
				'type'        => 'number',
				'description' => 'Number of blockchain confirmations required to consider payment complete.',
				'default'     => '10',
				'desc_tip'    => true,
			],
			'api_url'            => [
				'title'       => 'Blockchain Node API URL',
				'type'        => 'text',
				'description' => 'The URL of your blockchain node API. Example: http://37.27.100.59:10500/json_rpc',
				'default'     => 'http://37.27.100.59:10500/json_rpc',
				'desc_tip'    => true,
			],
			'payment_id_api_url' => [
				'title'       => 'Payment ID Verification API URL',
				'type'        => 'text',
				'description' => 'The base URL for Payment ID verification API. Use our free service or set up your own backend. Example: https://api.acceptanycoin.com',
				'default'     => AnyCoin_Constants::PAYMENT_VERIFICATION_API,
				'desc_tip'    => true,
			],
			'debug'              => [
				'title'       => 'Debug Log',
				'type'        => 'checkbox',
				'label'       => 'Enable logging',
				'default'     => 'no',
				'description' => 'Enable detailed logging for troubleshooting. Disable for production use to improve security and performance.',
			],
		];
	}

	/**
	 * Process the payment and return the result.
	 *
	 * @param int $order_id Order ID.
	 * @return array
	 */
	public function process_payment( $order_id ) {
		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			wc_add_notice( 'Order not found', 'error' );
			return [
				'result'   => 'failure',
				'redirect' => '',
			];
		}

		$usd_amount = floatval( $order->get_total() );

		if ( $this->debug ) {
			$this->log( 'Processing payment for order #' . $order_id . ' with amount $' . $usd_amount . ' USD' );
		}

		$buffer_percent = floatval( $this->price_buffer );

		$zano_amount = $this->api->convert_usd_to_zano( $usd_amount, $buffer_percent );

		if ( is_wp_error( $zano_amount ) ) {
			$this->log( 'Error converting to ZANO: ' . $zano_amount->get_error_message() . '. Falling back to direct amount.' );
			$zano_amount = $usd_amount;
		}

		$zano_amount = number_format( $zano_amount, 8, '.', '' );

		if ( $this->debug ) {
			$this->log( 'Final payment amount for order #' . $order_id . ': ' . $zano_amount . ' ZANO (with ' . $buffer_percent . '% buffer)' );
		}

		$payment_id = $this->api->generate_payment_id();

		$integrated_address = $this->api->generate_integrated_address( $payment_id );
		if ( is_wp_error( $integrated_address ) ) {
			if ( $this->debug ) {
				$this->log( 'Error generating integrated address: ' . $integrated_address->get_error_message() );
			}
			wc_add_notice( 'Error generating payment address. Please try again.', 'error' );
			return [
				'result'   => 'failure',
				'redirect' => '',
			];
		}

				$insert_id = AnyCoin_Database_Manager::insert_payment(
					[
						'order_id'       => (int) $order_id,
						'payment_id'     => $payment_id,
						'wallet_address' => $integrated_address,
						'amount'         => $zano_amount,
						'status'         => AnyCoin_Constants::STATUS_PENDING,
					]
				);

		if ( ! $insert_id ) {
			if ( $this->debug ) {
				$this->log( 'Database error when creating payment record (insert returned false).' );
			}
			wc_add_notice( 'Error processing payment. Please try again.', 'error' );
			return [
				'result'   => 'failure',
				'redirect' => '',
			];
		}

		$order->update_status( 'on-hold', 'Awaiting cryptocurrency payment' );

				$order->add_order_note(
					sprintf(
						'Awaiting payment of %s ZANO to integrated address %s (converted from $%s USD with %s%% buffer). Payment ID: %s',
						$zano_amount,
						$integrated_address,
						$usd_amount,
						$buffer_percent,
						$payment_id
					)
				);

		wc_reduce_stock_levels( $order_id );

		// Remove cart.
		WC()->cart->empty_cart();

		return [
			'result'   => 'success',
			'redirect' => add_query_arg(
				[
					'order_id' => $order_id,
					'key'      => $order->get_order_key(),
					'_wpnonce' => wp_create_nonce( 'anycoin_payment_page' ),
				],
				WC()->api_request_url( 'anycoin_payment_page' )
			),
		];
	}

	/**
	 * Output for the order received page.
	 *
	 * @param int $order_id Order ID.
	 */
	public function thankyou_page( $order_id ) {
		$order = wc_get_order( $order_id );

		if ( ! $order || $order->get_payment_method() !== $this->id ) {
			return;
		}

		if ( in_array( $order->get_status(), [ 'processing', 'completed' ], true ) ) {
			echo '<div class="woocommerce-notice woocommerce-notice--success">';
			echo '<p>Payment has been confirmed and your order is being processed. Thank you!</p>';
			echo '</div>';
			return;
		}

		echo '<div class="woocommerce-notice woocommerce-notice--info">';
				echo '<p>Your payment has been detected and will be confirmed soon. We are waiting for blockchain confirmations to complete your order.</p>';
		echo '<p>You will receive an email confirmation once your payment is fully processed. Thank you for your patience!</p>';
		echo '</div>';
	}

	/**
	 * Add content to the WC emails.
	 *
	 * @param WC_Order $order Order object.
	 * @param bool     $sent_to_admin Sent to admin.
	 * @param bool     $plain_text Email format: plain text or HTML.
	 */
	public function email_instructions( $order, $sent_to_admin, $plain_text = false ) {
		if ( $sent_to_admin || $order->get_payment_method() !== $this->id ) {
			return;
		}

		if ( in_array( $order->get_status(), [ 'processing', 'completed' ], true ) ) {
			return;
		}

		$payment = AnyCoin_Database_Manager::get_payment_by_order_id( (int) $order->get_id() );

		if ( ! $payment ) {
			return;
		}

		$amount = $payment['amount'];

		if ( $plain_text ) {
				echo "\n\nPayment Instructions:\n\n";
			echo 'Amount: ' . esc_html( $amount ) . " ZANO\n";
			echo 'Address: ' . esc_html( $payment['wallet_address'] ) . "\n";
			echo "Note: This integrated address includes payment tracking. Just send the exact amount to this address.\n";
		} else {
						echo '<h2>Payment Instructions</h2>';
			echo '<p>Please send the exact amount of cryptocurrency to the following address:</p>';
			echo '<ul>';
			echo '<li><strong>Amount:</strong> ' . esc_html( $amount ) . ' ZANO</li>';
			echo '<li><strong>Address:</strong> ' . esc_html( $payment['wallet_address'] ) . '</li>';
			echo '</ul>';
			echo '<p>Note: This integrated address includes payment tracking. Your payment will be confirmed after it reaches the required number of confirmations on the blockchain.</p>';
		}
	}

	/**
	 * Check if API connection is working.
	 *
	 * @return bool|WP_Error
	 */
	public function check_api_connection() {
		return $this->api->test_connection();
	}

	/**
	 * Validate API URL Field.
	 *
	 * @param string $key Field key.
	 * @param string $value Field value.
	 * @return string
	 */
	public function validate_api_url_field( $key, $value ) {
		if ( empty( $value ) ) {
			WC_Admin_Settings::add_error( 'API URL is required.' );
			return '';
		}

		if ( ! preg_match( '~^(?:f|ht)tps?://~i', $value ) ) {
			$value = 'http://' . $value;
		}

		if ( ! preg_match( '/json_rpc$/', $value ) ) {
			if ( substr( $value, -1 ) !== '/' ) {
				$value .= '/';
			}
			$value .= 'json_rpc';
		}

			return $value;
	}

	/**
	 * Validate wallet address field.
	 *
	 * @param string $key Field key.
	 * @param string $value Field value.
	 * @return string
	 */
	public function validate_wallet_address_field( $key, $value ) {
		if ( empty( $value ) ) {
			WC_Admin_Settings::add_error( 'Wallet address is required.' );
			return '';
		}

		if ( substr( $value, 0, 2 ) !== 'Zx' ) {
			WC_Admin_Settings::add_error( 'Invalid wallet address. Address must start with "Zx".' );
		}

			return $value;
	}

	/**
	 * Validate view key field.
	 *
	 * @param string $key Field key.
	 * @param string $value Field value.
	 * @return string
	 */
	public function validate_view_key_field( $key, $value ) {
		if ( empty( $value ) ) {
			WC_Admin_Settings::add_error( 'View key is required for payment verification.' );
			return '';
		}

		if ( ! ctype_xdigit( $value ) || ( strlen( $value ) !== 40 && strlen( $value ) !== 64 ) ) {
			WC_Admin_Settings::add_error( 'Invalid view key format. View key must be a 40 or 64 character hexadecimal string.' );
		}

			return $value;
	}

	/**
	 * Log debug messages.
	 *
	 * @param string $message Message to log.
	 */
	private function log( $message ) {
		if ( $this->debug ) {
			if ( function_exists( 'wc_get_logger' ) ) {
				$logger = wc_get_logger();
				$logger->debug( $message, [ 'source' => 'anycoin-payment' ] );
			}
		}
	}

	/**
	 * Render admin options with additional information
	 */
	public function admin_options() {
		?>
				<h2><?php echo esc_html( $this->get_method_title() ); ?> Settings</h2>
		
		<?php
		// Get current ZANO price.
		$price = $this->api->get_zano_price();
		if ( ! is_wp_error( $price ) ) {
			echo '<div class="notice notice-info inline">';
									echo '<p>' . sprintf(
										'Current ZANO price: $%s USD (from MEXC Exchange)',
										number_format( $price, 2 )
									) . '</p>';
			echo '</div>';
		}
		?>
		
		<table class="form-table">
			<?php $this->generate_settings_html(); ?>
		</table>
		<?php
	}
}
