<?php

/**
 * Payment Processor
 *
 * Handles renewal order payment routing.
 *
 * @package ArraySubs\Features\RecurringBilling\Services
 * @since 1.0.0
 */

namespace ArraySubs\Features\RecurringBilling\Services;

defined('ABSPATH') || exit;

/**
 * Payment processor service
 */
class PaymentProcessor
{
    /**
     * Process payment for renewal order
     *
    * Checks if the subscription uses an automatic payment gateway. If so,
    * delegates to the gateway system through a returnable result filter.
    * Otherwise, falls back to manual payment.
     *
     * @param int       $subscription_id Subscription ID
     * @param \WC_Order $order Renewal order
    * @return array Result with status, success, message, and optional order/payment data.
     */
    public function processPayment(int $subscription_id, $order): array
    {
        $subscription = arraysubs_get_subscription($subscription_id);

        if (!$subscription) {
            return [
                'success' => false,
                'message' => __('Subscription not found', 'arraysubs'),
            ];
        }

        if ($order->is_paid()) {
            return [
                'success'                 => true,
                'status'                  => 'paid',
                'message'                 => __('Renewal order is already paid.', 'arraysubs'),
                'order_id'                => $order->get_id(),
                'requires_manual_payment' => false,
                'payment_mode'            => 'none',
            ];
        }

        if ((float) $order->get_total() <= 0) {
            $order->add_order_note(
                __('Renewal order total is zero. Marking paid without gateway charge.', 'arraysubs')
            );
            $order->payment_complete('renewal_zero_amount');

            return [
                'success'                 => true,
                'status'                  => 'paid',
                'message'                 => __('Renewal order paid in full without gateway charge.', 'arraysubs'),
                'order_id'                => $order->get_id(),
                'requires_manual_payment' => false,
                'payment_mode'            => 'none',
            ];
        }

        // Check if the pro gateway system handles this subscription
        $is_automatic = apply_filters('arraysubs_is_automatic_payment', false, $subscription_id);

        if ($is_automatic) {
            $should_process = apply_filters(
                'arraysubs_should_process_automatic_payment',
                true,
                $subscription_id,
                $order
            );

            if ($should_process) {
                $result = apply_filters(
                    'arraysubs_process_automatic_renewal_payment',
                    [],
                    $subscription_id,
                    $order
                );

                return $this->normalizeAutomaticResult($result, $order);
            }
        }

        // Manual payment fallback
        $order->add_order_note(
            __('Renewal order created. Awaiting manual payment.', 'arraysubs')
        );

        $payment_url = $order->get_checkout_payment_url();

        return [
            'success'                 => true,
            'status'                  => 'manual_required',
            'message'                 => __('Renewal order created successfully. Manual payment required.', 'arraysubs'),
            'order_id'                => $order->get_id(),
            'payment_url'             => $payment_url,
            'requires_manual_payment' => true,
            'payment_mode'            => 'manual',
        ];
    }

    /**
     * Normalize an automatic gateway result.
     *
     * @param mixed     $result Gateway result.
     * @param \WC_Order $order  Renewal order.
     * @return array Normalized result.
     */
    private function normalizeAutomaticResult($result, $order): array
    {
        if (!is_array($result) || empty($result)) {
            return [
                'success'                 => false,
                'status'                  => 'failed',
                'message'                 => __('Automatic renewal gateway did not return a payment result.', 'arraysubs'),
                'order_id'                => $order->get_id(),
                'requires_manual_payment' => false,
                'payment_mode'            => 'automatic',
            ];
        }

        $status = $result['status'] ?? '';

        if ($order->is_paid()) {
            $status = 'paid';
        } elseif (empty($status)) {
            if (!empty($result['requires_action'])) {
                $status = 'requires_action';
            } elseif (!empty($result['success'])) {
                $status = 'pending';
            } else {
                $status = 'failed';
            }
        }

        return array_merge([
            'success'                 => $order->is_paid() || !empty($result['success']),
            'status'                  => $status,
            'message'                 => __('Renewal payment captured.', 'arraysubs'),
            'order_id'                => $order->get_id(),
            'requires_manual_payment' => false,
            'payment_mode'            => 'automatic',
        ], $result, ['status' => $status]);
    }

    /**
     * Check if an order has been paid manually
     * This can be used by external processes to check payment status
     *
     * @param \WC_Order $order Order to check
     * @return bool True if order is paid
     */
    public function isOrderPaid($order): bool
    {
        return $order->is_paid();
    }

    /**
     * Get payment URL for a renewal order
     *
     * @param \WC_Order $order Renewal order
     * @return string Payment URL
     */
    public function getPaymentUrl($order): string
    {
        return $order->get_checkout_payment_url();
    }
}
