<?php
// If this file is called directly, abort.
if (! defined('ABSPATH')) {
    die;
}
/**
 * Sends WooCommerce order change events to NoParcels so orders are imported without manual refresh.
 */
class MP_Webhooks
{
    private const ENDPOINT = 'https://app.noparcels.com/shops/woocommerce/webhook/orderactions';
	
    public function __construct()
    {
        add_action('woocommerce_checkout_order_processed', [$this, 'checkout_order_processed'], 20, 1);
        add_action('woocommerce_order_refunded', [$this, 'order_refunded'], 20, 2);

        add_action('woocommerce_order_status_changed', [$this, 'order_status_changed'], 20, 4);
    }
	
    public function checkout_order_processed($order_id)
	{
		if (! function_exists('wc_get_order')) {
			return;
		}
		$order = wc_get_order((int) $order_id);
		if (! $order) {
			return;
		}
		$this->send_order_event((int) $order_id, 'order.created', $order);
	}
	
    public function order_status_changed($order_id, $old_status, $new_status, $order)
	{
		if ($old_status === $new_status) {
			return;
		}
		// Jeigu statusas pakeistas į on-hold — nesiunčiam į NoParcels
		if ($new_status === 'on-hold') {
			return;
		}
		$this->send_order_event((int) $order_id, 'order.status_changed', $order, [
			'old_status' => $old_status,
			'new_status' => $new_status,
		]);
	}
	
	public function order_refunded($order_id, $refund_id)
	{
		$order = wc_get_order((int) $order_id);
		if (! $order) {
			return;
		}
		$refund = wc_get_order((int) $refund_id);
		$refunded_items = [];
		if ($refund) {
			foreach ($refund->get_items() as $item) {
				$refunded_items[] = [
					'product_id' => (int) $item->get_product_id(),
					'variation_id' => (int) $item->get_variation_id(),
					'quantity' => abs((int) $item->get_quantity()),
					'total' => abs((float) $item->get_total()),
				];
			}
		}
		$remaining_items_count = 0;
		foreach ($order->get_items() as $item_id => $item) {
			$qty = (int) $item->get_quantity();
			$refunded_qty = abs((int) $order->get_qty_refunded_for_item($item_id));
			$remaining_qty = max(0, $qty - $refunded_qty);
			$remaining_items_count += $remaining_qty;
		}
		$this->send_order_event((int) $order_id, 'order.refunded', $order, [
			'refund_id' => (int) $refund_id,
			'new_status' => $order->get_status(),
			'refund_total' => $refund ? abs((float) $refund->get_total()) : 0,
			'order_total' => (float) $order->get_total(),
			'remaining_items_count' => $remaining_items_count,
			'fully_refunded' => $remaining_items_count === 0,
			'refunded_items' => $refunded_items,
		]);
	}
	
    private function send_order_event(int $order_id, string $event, $order = null, array $extra = []): void
    {
        if ($order_id <= 0) {
            return;
        }
        if (! function_exists('wc_get_order')) {
            return;
        }
        $api_key = MultiParcels()->options->get_api_key();
        if (! $api_key) {
            return;
        }
        if (! $order) {
			$order = wc_get_order($order_id);
		}
		if (! $order) {
			return;
		}
		$order_status = $order->get_status();
		$allowed_statuses = [
			'processing',
			'completed',
			'cancelled',
			'refunded',
			'failed',
		];
		if ($event !== 'order.refunded' && ! in_array($order_status, $allowed_statuses, true)) {
			return;
		}
        $payload = array_merge([
            'event' => $event,
            'order_id' => $order_id,
            'order_status' => $order_status,
            'site_url' => home_url(),
            'wp_url' => get_bloginfo('wpurl'),
            'sent_at' => gmdate('c'),
        ], $extra);
        $response = wp_remote_post(self::ENDPOINT, [
            'timeout' => 10,
			'blocking' => true,
            'headers' => [
                'Accept' => 'application/json',
                'Content-Type' => 'application/json',
                'Authorization' => 'Bearer ' . $api_key,
                'X-NoParcels-Source' => home_url(),
                'X-NoParcels-Event' => $event,
            ],
            'body' => wp_json_encode($payload),
            'data_format' => 'body',
        ]);
        if (is_wp_error($response)) {
            error_log('NoParcels order webhook failed to dispatch: ' . $response->get_error_message());
        }
        $status = (int) wp_remote_retrieve_response_code($response);
        if ($status < 200 || $status >= 300) {
            error_log('NoParcels order webhook returned HTTP ' . $status . ': ' . wp_remote_retrieve_body($response));
        }
    }
	
}
return new MP_Webhooks();