<?php

namespace ChinaPayments;

use ChinaPayments\PaymentGateway as CP_PaymentGateway;

class ActionScheduler {

  /**
   * @var null|ActionScheduler;
   */
  protected static $_instance = null;

  /**
   * @return ActionScheduler
   */
  public static function instance(): ActionScheduler {
    if ( self::$_instance === null ) {
      self::$_instance = new self();
    }

    return self::$_instance;
  }

  /**
   * At the moment, the purpose for this, is strictly for WooCommerce, which includes Action Scheduler by default.
   * @return void
   */
  public function setup() {
    if( did_action('plugins_loaded') ) {
      $this->_register_action_scheduler();
    } else {
      add_action( 'plugins_loaded', [ $this, '_register_action_scheduler' ], 99 );
    }
  }

  public function _register_action_scheduler() {
    if( !function_exists( 'as_has_scheduled_action' ) )
      return;

    if( !function_exists('WC'))
      return;

    if( !apply_filters( 'china_payments_woocommerce_has_background_payment_check', true ) )
      return;

    add_action( 'init', [ $this, '_init' ], 99 );
    add_action( 'china_payments_woocommerce_background_payment_check', [ $this, '_china_payments_woocommerce_background_payment_check' ] );
    add_action( 'china_payments_woocommerce_process_payment', [ $this, '_china_payments_woocommerce_process_payment' ], 10, 2 );
  }

  public function _init() {
    if ( false === as_has_scheduled_action( 'china_payments_woocommerce_background_payment_check' ) ) {
      as_schedule_recurring_action( strtotime( 'now' ), MINUTE_IN_SECONDS * 15, 'china_payments_woocommerce_background_payment_check' );
    }
  }

  public function _china_payments_woocommerce_background_payment_check() {
    if( !apply_filters( 'china_payments_woocommerce_has_background_payment_check', true ) )
      return;

    $order_ids = china_payments_woocommerce_stripe_awaiting_payments_order_ids();

    if(empty($order_ids))
      return;

    foreach( $order_ids as $order_id ) {
      $order = wc_get_order( $order_id );

      if(empty($order))
        continue;

      $is_live           = $order->get_meta( 'china_payments_is_live' );
      $payment_intent_id = $order->get_meta( 'china_payments_payment_intent_id' );

      if ( empty( $payment_intent_id ) ) {
        continue;
      }

      $stripeIntegration = CP_PaymentGateway::get_integration_from_settings( 'stripe', $is_live );

      try {
        $payment_intent = $stripeIntegration->stripeClient()->paymentIntents->retrieve( $payment_intent_id );

        if ( $payment_intent->status === 'succeeded' ) {
          if ( ! $order->is_paid() ) {
            $order->payment_complete( $payment_intent->id );
          }
        }
      } catch ( \Exception $e ) {
      }
    }
  }

  /**
   * Queue a one-off async job to finish a WooCommerce order off the back of a
   * verified Stripe webhook, so the webhook request itself can return instantly.
   *
   * @param int $order_id WooCommerce order ID.
   * @param int $is_live  1 for live mode, 0 for test mode.
   * @return bool True if queued for async processing; false when Action Scheduler
   *              is unavailable (the caller should then process inline).
   */
  public static function enqueue_webhook_payment( $order_id, $is_live ): bool {
    if ( ! function_exists( 'as_enqueue_async_action' ) ) {
      return false;
    }

    as_enqueue_async_action(
      'china_payments_woocommerce_process_payment',
      array( absint( $order_id ), (int) $is_live ),
      'china-payments'
    );

    return true;
  }

  /**
   * Async worker: verify a single order's PaymentIntent with Stripe and complete
   * the order if the payment succeeded. Idempotent — re-checks is_paid() before
   * completing, so duplicate webhook deliveries and retries are harmless.
   *
   * @param int $order_id WooCommerce order ID.
   * @param int $is_live  1 for live mode, 0 for test mode.
   * @return void
   */
  public function _china_payments_woocommerce_process_payment( $order_id = 0, $is_live = 0 ) {
    $order_id = absint( $order_id );

    if ( ! $order_id || ! function_exists( 'wc_get_order' ) ) {
      return;
    }

    $order = wc_get_order( $order_id );

    if ( ! $order instanceof \WC_Order || $order->is_paid() ) {
      return;
    }

    $payment_intent_id = $order->get_meta( 'china_payments_payment_intent_id' );

    if ( empty( $payment_intent_id ) ) {
      return;
    }

    $stripeIntegration = CP_PaymentGateway::get_integration_from_settings( 'stripe', $is_live );

    try {
      $payment_intent = $stripeIntegration->stripeClient()->paymentIntents->retrieve( $payment_intent_id );

      if ( $payment_intent->status === 'succeeded' && ! $order->is_paid() ) {
        $order->payment_complete( $payment_intent->id );
      }
    } catch ( \Exception $e ) {
      // Leave it to the recurring reconciliation sweep as a fallback.
      error_log( '[China Payments] Async webhook payment processing failed for order ' . $order_id . ': ' . $e->getMessage() );
    }
  }

}