<?php

namespace KrokedilKlarnaPaymentsDeps\Krokedil\KlarnaExpressCheckout\Api\Notifications;

use Krokedil\Klarna\PluginFeatures;
use KrokedilKlarnaPaymentsDeps\Krokedil\KlarnaExpressCheckout\Interfaces\AcquiringPartnerIntegration;
\defined('ABSPATH') || exit;
abstract class Handler
{
    /**
     * The event type for the notification.
     *
     * @var string
     */
    protected $event_type;
    /**
     * The version for the notification.
     *
     * @var string
     */
    protected $event_version;
    /**
     * Check if the event type and version matches the notification handler.
     *
     * @param string $event_type    The event type to check.
     * @param string $event_version The version to check.
     */
    public function matches($event_type, $event_version)
    {
        return $this->event_type === $event_type && $this->event_version === $event_version;
    }
    /**
     * Get the Acquiring Partner integration class to use for this notification.
     *
     * @return AcquiringPartnerIntegration|null
     */
    public function get_acquiring_partner_integration()
    {
        $ap_key = PluginFeatures::get_acquiring_partner_key();
        $integrations = apply_filters('kec_acquiring_partner_integrations', []);
        foreach ($integrations as $integration) {
            if ($integration->get_key() === $ap_key) {
                return $integration;
            }
        }
        return null;
    }
    /**
     * Handle the notification callback.
     *
     * @param array         $payload The payload from the notification.
     *
     * @return \WP_REST_Response|null
     * @throws \WP_Exception If the notification cannot be handled.
     */
    public abstract function handle_notification($payload);
    /**
     * Retrieve a WooCommerce order by its associated Klarna payment request ID.
     *
     * @param string $payment_request_id The Klarna payment request ID.
     * @throws \WP_Exception If no valid order is found.
     * @return \WC_Order|null The WooCommerce order if found, null otherwise.
     */
    protected function get_wc_order_by_payment_request_id($payment_request_id)
    {
        // Find the order associated with this payment request ID.
        $args = array(
            'limit' => 1,
            'meta_key' => '_kec_payment_request_id',
            'meta_value' => $payment_request_id,
            'meta_compare' => '=',
            'created_via' => 'klarna_express_checkout',
            // Only look for orders created via KEC.
            'date_created' => '>' . (\time() - DAY_IN_SECONDS * 2),
        );
        $orders = wc_get_orders($args);
        $order = !empty($orders) && \is_array($orders) ? $orders[0] : null;
        $this->ensure_valid_order($order, $payment_request_id);
        return $order;
    }
    /**
     * Ensure the order returned is valid for the payment request id.
     *
     * @param \WC_Order|null $order The order to validate.
     * @param string $payment_request_id The payment request id to validate against.
     *
     * @throws \WP_Exception If the order is not valid.
     * @return void
     */
    protected function ensure_valid_order($order, $payment_request_id)
    {
        if (empty($order)) {
            throw new \WP_Exception('No draft order found for payment request ID: ' . $payment_request_id);
        }
        // Ensure the metadata of the order is actually the payment request ID.
        $stored_payment_request_id = $order->get_meta('_kec_payment_request_id');
        if ($stored_payment_request_id !== $payment_request_id) {
            throw new \WP_Exception('Mismatch in payment request ID for order ID: ' . $order->get_id());
        }
        return $order;
    }
}
