<?php
/**
 * Copyright © Simplyin. All rights reserved.
 */
declare(strict_types=1);

namespace Simplyin\Payment\Model\Queue;

use Simplyin\Payment\Helper\ApiClient;
use Simplyin\Payment\Model\OrderSyncFactory;
use Simplyin\Payment\Model\ResourceModel\OrderSync as OrderSyncResource;
use Simplyin\Payment\Model\ResourceModel\OrderSync\CollectionFactory as OrderSyncCollectionFactory;
use Magento\Sales\Api\OrderRepositoryInterface;
use Psr\Log\LoggerInterface;

/**
 * Async consumer for post-placement order sync to SimplyIN
 *
 * After a Magento order is placed, this consumer handles:
 * - Creating/updating the sync record in simplyin_order_sync table
 * - Linking the email to the sales order in Zoho (if applicable)
 * - Any other post-placement API operations
 *
 * This keeps the checkout response fast by deferring non-critical operations.
 */
class OrderSyncPostPlacementConsumer
{
    /**
     * @var ApiClient
     */
    private $apiClient;

    /**
     * @var OrderSyncFactory
     */
    private $orderSyncFactory;

    /**
     * @var OrderSyncResource
     */
    private $orderSyncResource;

    /**
     * @var OrderSyncCollectionFactory
     */
    private $orderSyncCollectionFactory;

    /**
     * @var OrderRepositoryInterface
     */
    private $orderRepository;

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @param ApiClient $apiClient
     * @param OrderSyncFactory $orderSyncFactory
     * @param OrderSyncResource $orderSyncResource
     * @param OrderSyncCollectionFactory $orderSyncCollectionFactory
     * @param OrderRepositoryInterface $orderRepository
     * @param LoggerInterface $logger
     */
    public function __construct(
        ApiClient $apiClient,
        OrderSyncFactory $orderSyncFactory,
        OrderSyncResource $orderSyncResource,
        OrderSyncCollectionFactory $orderSyncCollectionFactory,
        OrderRepositoryInterface $orderRepository,
        LoggerInterface $logger
    ) {
        $this->apiClient = $apiClient;
        $this->orderSyncFactory = $orderSyncFactory;
        $this->orderSyncResource = $orderSyncResource;
        $this->orderSyncCollectionFactory = $orderSyncCollectionFactory;
        $this->orderRepository = $orderRepository;
        $this->logger = $logger;
    }

    /**
     * Process post-placement sync message
     *
     * @param string $message JSON encoded message
     * @return void
     */
    public function process(string $message): void
    {
        try {
            $data = json_decode($message, true);

            if (!$data || empty($data['orderId'])) {
                $this->logger->warning('SimplyIN Queue: Invalid post-placement sync message');
                return;
            }

            $orderId = (int)$data['orderId'];
            $simplyinOrderId = $data['simplyinOrderId'] ?? '';

            $this->logger->info('SimplyIN Queue: Processing post-placement sync', [
                'order_id' => $orderId,
                'simplyin_order_id' => $simplyinOrderId
            ]);

            // Create/update sync record
            $now = (new \DateTime())->format('Y-m-d H:i:s');
            $collection = $this->orderSyncCollectionFactory->create();
            $collection->addFieldToFilter('order_id', $orderId);
            $existingRecord = $collection->getFirstItem();

            if ($existingRecord && $existingRecord->getId()) {
                if ($simplyinOrderId) {
                    $existingRecord->setSimplyinOrderId($simplyinOrderId);
                }
                $existingRecord->setSyncStatus('synced');
                $existingRecord->setLastSyncAt($now);
                $this->orderSyncResource->save($existingRecord);
            } else {
                $orderSync = $this->orderSyncFactory->create();
                $orderSync->setOrderId($orderId);
                if ($simplyinOrderId) {
                    $orderSync->setSimplyinOrderId($simplyinOrderId);
                }
                $orderSync->setSyncStatus('synced');
                $orderSync->setLastSyncAt($now);
                $this->orderSyncResource->save($orderSync);
            }

            $this->logger->info('SimplyIN Queue: Post-placement sync completed', [
                'order_id' => $orderId
            ]);

        } catch (\Exception $e) {
            $this->logger->error('SimplyIN Queue: Exception in post-placement sync', [
                'error' => $e->getMessage(),
                'message' => substr($message, 0, 200)
            ]);
        }
    }
}
