<?php

namespace Easymailing\App\Core\Provider\Woocommerce\Service;

use Easymailing\App\Api\Client;
use Easymailing\App\Core\Log\LogManager;
use Easymailing\App\Core\Provider\Woocommerce\Model\LogType;
use Easymailing\App\Model\Order;
use Easymailing\App\Repository\ConfigRepository;

class OrderStatusHandler
{

	private $config;
	private $apiClient;
	private $logManager;

	public function __construct(
		ConfigRepository $configRepository,
		Client $apiClient,
		LogManager $logManager
	)
	{
		$this->config = $configRepository->getSynchronizationConfig();
		$this->apiClient = $apiClient;
		$this->logManager = $logManager;
	}

	public function synchronizeOrderStatus(Order $orderResource, \WC_Order $order): void
	{
		if($order->get_status() === 'pending' or $order->get_status() === 'on-hold'){
			if($orderResource->status === 'cart') {
				$this->processOrder($order->get_id());
			}
		}

		if($order->get_status() === 'processing'){
			if($orderResource->status === 'cart'){
				$this->processOrder($order->get_id());
				$this->payOrder($order->get_id());
			}
			if($orderResource->status === 'new') {
				$this->payOrder($order->get_id());
			}
		}

		if($order->get_status() === 'completed'){
			if($orderResource->status === 'cart'){
				$this->processOrder($order->get_id());
				$this->payOrder($order->get_id());
				$this->shipOrder($order->get_id());
				return;
			}

			if($orderResource->status === 'new') {
				$this->payOrder($order->get_id());
				$this->shipOrder($order->get_id());
				return;
			}

			if($orderResource->status === 'paid') {
				$this->shipOrder($order->get_id());
				return;
			}

			if($orderResource->status !== 'shipped') {
				$this->shipOrder($order->get_id());
			}
		}

		if($order->get_status() === 'refunded'){
			if($orderResource->status === 'cart'){
				$this->processOrder($order->get_id());
				$this->refundOrder($order->get_id());
			}
			if($orderResource->status !== 'refunded') {
				$this->refundOrder($order->get_id());
			}
		}

		if($order->get_status() === 'cancelled'){
			if($orderResource->status === 'cart'){
				$this->processOrder($order->get_id());
				$this->cancelOrder($order->get_id());
			}
			if($orderResource->status !== 'cancelled') {
				$this->cancelOrder($order->get_id());
			}
		}
	}


	public function processOrder(int $orderId): void
	{
		$this->logManager->createLog(LogType::INFO, sprintf("Process order: %s", $orderId));
		$order = wc_get_order($orderId);
		$body = [
			'order_number' => $order->get_order_number(),
			'processed_at' => (new \DateTime("now", new \DateTimeZone("UTC")))->format('Y-m-d\TH:i:s\Z'),
		];
		$this->handleOrderAction($orderId, 'process_order', $body);
	}

	public function payOrder(int $orderId): void
	{
		$this->logManager->createLog(LogType::INFO, sprintf("Pay order: %s", $orderId));
		$body = [
			'paid_at' => (new \DateTime("now", new \DateTimeZone("UTC")))->format('Y-m-d\TH:i:s\Z'),
		];
		$this->handleOrderAction($orderId, 'pay_order', $body);
	}

	public function refundOrder(int $orderId): void
	{
		$this->logManager->createLog(LogType::INFO, sprintf("Refund order: %s", $orderId));
		$body = [];
		$this->handleOrderAction($orderId, 'refund_order', $body);
	}

	public function cancelOrder(int $orderId): void
	{
		$this->logManager->createLog(LogType::INFO, sprintf("Cancel order: %s", $orderId));
		$body = [
			'cancelled_at' => (new \DateTime("now", new \DateTimeZone("UTC")))->format('Y-m-d\TH:i:s\Z'),
		];
		$this->handleOrderAction($orderId, 'cancel_order', $body);
	}

	public function shipOrder(int $orderId): void
	{
		$this->logManager->createLog(LogType::INFO, sprintf("Cancel order: %s", $orderId));
		$body = [
			'tracking_number' => '',
			'tracking_carrier' => '',
			'tracking_url' => '',
		];
		$this->handleOrderAction($orderId, 'ship_order', $body);
	}

	private function handleOrderAction(int $orderId, string $action, array $body): void
	{
		$orderResourceId = get_post_meta($orderId, MetadataHelper::getResourceId(), true);
		if (!$orderResourceId) {
			$this->logManager->createLog(LogType::ERROR, "Order {$action} error: Order resource ID not found");
			return;
		}

		$url = sprintf("/stores/%s/orders/%s/actions/%s", $this->config->getShopId(), $orderResourceId, $action);

		try {
			$this->apiClient->handleOrder($url, $body);
		} catch (\Exception $e) {
			$this->logManager->createLog(LogType::ERROR, sprintf("handleOrderAction - Action: {$action}. error: %s", $e->getMessage()));
		}
	}
}
