<?php

if (!defined('ABSPATH')) {
	exit;
}

class R123_WC_Order_Sync {
	public static function init(): void {
		add_action('woocommerce_order_status_completed', [self::class, 'on_completed'], 20, 1);
		add_action('r123_wc_retry_failed_jobs', [self::class, 'retry_failed_jobs']);
	}

	public static function on_completed(int $order_id): void {
		self::sync_order($order_id, 'completed', false);
	}

	public static function retry_failed_jobs(): void {
		$orders = wc_get_orders([
			'limit'      => 20,
			'return'     => 'ids',
			'meta_key'   => '_r123_sync_failed',
			'meta_value' => 'yes',
		]);

		foreach ($orders as $order_id) {
			self::sync_order((int) $order_id, 'retry', true);
		}
	}

	public static function sync_order(int $order_id, string $trigger = 'manual', bool $force = false): bool {
		try {
			$order = wc_get_order($order_id);

			if (!$order) {
				throw new RuntimeException('Woo order not found');
			}

			$client = new R123_WC_API_Client();

			if (!$client->is_configured()) {
				throw new RuntimeException('Webhook URL ali API ključ ni nastavljen.');
			}

			$payload       = R123_WC_Order_Mapper::map_order($order, $trigger);
			$current_hash  = md5((string) wp_json_encode($payload));
			$existing_hash = (string) get_post_meta($order_id, '_r123_sync_hash', true);
			$sync_status   = (string) get_post_meta($order_id, '_r123_invoice_status', true);
			$invoice_id    = (string) get_post_meta($order_id, '_r123_invoice_id', true);

			$already_synced = (
				$existing_hash !== '' &&
				$existing_hash === $current_hash &&
				in_array($sync_status, ['received', 'warning'], true) &&
				$invoice_id !== ''
			);

			if (!$force && $trigger === 'completed' && $already_synced) {
				update_post_meta($order_id, '_r123_last_synced_at', current_time('mysql'));
				delete_post_meta($order_id, '_r123_sync_failed');

				return true;
			}

			$response = $client->send_order($payload);

			$received       = !empty($response['received']);
			$invoice_id     = sanitize_text_field((string) ($response['invoiceId'] ?? ''));
			$invoice_number = sanitize_text_field((string) ($response['invoiceNumber'] ?? ''));
			$pdf_url        = esc_url_raw((string) ($response['pdfUrl'] ?? ''));
			$error_message  = sanitize_text_field((string) ($response['error'] ?? ''));

			if (!$received) {
				throw new RuntimeException('Račun123 ni potrdil sprejema naročila.');
			}

			if ($invoice_id === '') {
				throw new RuntimeException('Račun123 ni vrnil invoiceId.');
			}

			update_post_meta($order_id, '_r123_sync_hash', $current_hash);
			update_post_meta($order_id, '_r123_invoice_id', $invoice_id);
			update_post_meta($order_id, '_r123_last_synced_at', current_time('mysql'));

			if ($invoice_number !== '') {
				update_post_meta($order_id, '_r123_invoice_number', $invoice_number);
			} else {
				delete_post_meta($order_id, '_r123_invoice_number');
			}

			if ($pdf_url !== '') {
				update_post_meta($order_id, '_r123_pdf_url', $pdf_url);
			} else {
				delete_post_meta($order_id, '_r123_pdf_url');
			}

			if ($error_message !== '') {
				update_post_meta($order_id, '_r123_invoice_status', 'warning');
				update_post_meta($order_id, '_r123_last_error', $error_message);
				delete_post_meta($order_id, '_r123_sync_failed');

				$note = 'Račun123 sync delno uspešen (' . $trigger . '). Invoice ID: ' . $invoice_id;

				if ($invoice_number !== '') {
					$note .= ', Št. računa: ' . $invoice_number;
				}

				$note .= '. Opozorilo: ' . $error_message;

				$order->add_order_note($note);

				R123_WC_Logger::log('warning', 'Order sync completed with warning', [
					'order_id'       => $order_id,
					'trigger'        => $trigger,
					'force'          => $force,
					'invoice_id'     => $invoice_id,
					'invoice_number' => $invoice_number,
					'pdf_url'        => $pdf_url,
					'warning'        => $error_message,
					'response'       => $response,
				]);

				return true;
			}

			update_post_meta($order_id, '_r123_invoice_status', 'received');
			delete_post_meta($order_id, '_r123_sync_failed');
			delete_post_meta($order_id, '_r123_last_error');

			$note = 'Račun123 sync uspešen (' . $trigger . '). Invoice ID: ' . $invoice_id;

			if ($invoice_number !== '') {
				$note .= ', Št. računa: ' . $invoice_number;
			}

			$order->add_order_note($note);

			R123_WC_Logger::log('info', 'Order sync success', [
				'order_id'       => $order_id,
				'trigger'        => $trigger,
				'force'          => $force,
				'invoice_id'     => $invoice_id,
				'invoice_number' => $invoice_number,
				'pdf_url'        => $pdf_url,
				'response'       => $response,
			]);

			return true;
		} catch (Throwable $e) {
			update_post_meta($order_id, '_r123_sync_failed', 'yes');
			update_post_meta($order_id, '_r123_last_error', sanitize_text_field($e->getMessage()));
			update_post_meta($order_id, '_r123_last_synced_at', current_time('mysql'));
			update_post_meta($order_id, '_r123_invoice_status', 'error');

			$order = wc_get_order($order_id);

			if ($order) {
				$order->add_order_note(
					'Račun123 sync napaka (' . $trigger . '): ' . sanitize_text_field($e->getMessage())
				);
			}

			R123_WC_Logger::log('error', 'Order sync failed', [
				'order_id' => $order_id,
				'trigger'  => $trigger,
				'force'    => $force,
				'error'    => $e->getMessage(),
			]);

			return false;
		}
	}
}