<?php

namespace PortalPeople\virtualstock\services;

use Yii;
use yii\base\BaseObject;
use PortalPeople\virtualstock\components\VirtualStockClient;
use PortalPeople\virtualstock\models\Cart;
use NGauge_Base\common\components\Tracing;

class VirtualStockService extends BaseObject
{
    public VirtualStockClient $client;
    public OrderService $orderService;
    public ProductService $productService;

    public function init(): void
    {
        parent::init();
    }

    /**
     * Update remote order using payload or status and persist response on the cart.
     */
    public function updateOrderFromCart(Cart $cart, $payload, ?string $status = null)
    {
        $orderNo = $cart->ordernumber ?? null;
        if (empty($orderNo)) {
            throw new \InvalidArgumentException('No VirtualStock order identifier on cart');
        }

        $span = Tracing::startSpan('virtualstock.updateOrder', ['cartId' => $cart->id ?? null, 'orderNo' => $orderNo]);

        $payloadData = $this->orderService->prepareUpdatePayload($payload);
        $send = [];
        if ($status !== null) {
            $send['status'] = (string)$status;
        }
        if ($payloadData !== []) {
            $send = array_merge($send, $payloadData);
        }

        if ($send === []) {
            throw new \InvalidArgumentException('Nothing to send');
        }

        try {
            $resp = $this->client->updateOrder($orderNo, $send);
            Cart::appendVirtualStockApiResponse($cart, $resp);
            Tracing::endSpan($span, ['result' => is_string($resp) ? $resp : 'ok']);
        } catch (\Throwable $e) {
            Tracing::endSpan($span, ['error' => 'update_failed', 'message' => $e->getMessage()]);
            throw $e;
        }

        // Attempt to map response into cart when mappable
        if (is_array($resp) && count($resp) > 0) {
            try {
                Cart::applyVirtualStockOrderData($cart, $resp, $orderNo, Yii::$app->getModule('virtualstock'));
                $cart->save(false);
            } catch (\Throwable $e) {
                Yii::warning('Failed to map update response into cart: ' . $e->getMessage(), 'virtualstock');
            }
        }

        return $resp;
    }

    public function acknowledgeOrderFromCart(Cart $cart)
    {
        $orderNo = json_decode($cart->imported_data ?? '{}', true)['url'] ?? $cart->ordernumber ?? null;
        if (empty($orderNo)) {
            throw new \InvalidArgumentException('No VirtualStock order identifier on cart');
        }

        $span = Tracing::startSpan('virtualstock.ack.order', ['cartId' => $cart->id ?? null, 'orderNo' => $orderNo]);
        try {
            $payload = $this->orderService->buildAcknowledgePayloadFromCart($cart);
            $resp = $this->client->acknowledgeOrder($orderNo, $payload['items'] ?? []);
            Cart::appendVirtualStockApiResponse($cart, $resp);
            Tracing::endSpan($span, ['result' => is_string($resp) ? $resp : 'ok']);
            return $resp;
        } catch (\Throwable $e) {
            Tracing::endSpan($span, ['error' => 'ack_failed', 'message' => $e->getMessage()]);
            throw $e;
        }
    }

    public function dispatchOrderFromCart(Cart $cart)
    {
        $orderNo = json_decode($cart->imported_data ?? '{}', true)['url'] ?? $cart->ordernumber ?? null;
        if (empty($orderNo)) {
            throw new \InvalidArgumentException('No VirtualStock order identifier on cart');
        }

        $span = Tracing::startSpan('virtualstock.dispatch.order', ['cartId' => $cart->id ?? null, 'orderNo' => $orderNo]);
        try {
            $payload = $this->orderService->buildDispatchPayloadFromCart($cart);
            $resp = $this->client->dispatchOrder($orderNo, $payload);
            Cart::appendVirtualStockApiResponse($cart, $resp);
            Tracing::endSpan($span, ['result' => is_string($resp) ? $resp : 'ok']);
            return $resp;
        } catch (\Throwable $e) {
            Tracing::endSpan($span, ['error' => 'dispatch_failed', 'message' => $e->getMessage()]);
            throw $e;
        }
    }
}
