<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 0");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

$data = json_decode(file_get_contents("php://input"));
$quoteId = (isset($data->quote_id) && $data->quote_id > 0) ? $data->quote_id : 0;

// Authorization Check
list($message, $messageSuccess, $accessToken) = validateAuthorization();

// Bootstrap Magento
require '../../app/bootstrap.php';
use Magento\Framework\App\Bootstrap;
use Magento\Quote\Api\CartManagementInterface;
use Magento\Quote\Model\QuoteFactory;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\DataObject;
use Magento\Framework\App\ResourceConnection;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Integration\Model\Oauth\Token as OAuthToken;
use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory as QuoteCollectionFactory;
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get(\Magento\Framework\App\State::class);
$state->setAreaCode('frontend');

// Inject dependencies
$cartManagement = $objectManager->get(CartManagementInterface::class);
$quoteRepository = $objectManager->get(\Magento\Quote\Model\QuoteRepository::class);
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
$quoteCollectionFactory = $objectManager->get(QuoteCollectionFactory::class);
$connection = $objectManager->get(ResourceConnection::class)->getConnection();
$oauthToken = $objectManager->get(OAuthToken::class);

$result = [
    "message" => $message,
    "success" => $messageSuccess,
    "outofstock" => [],
    "quote_id" => $quoteId,
    'subtotal' => 0,
];

// Log request
logRequest($connection, $quoteId, $accessToken, $data);

if (isset($data->customer_id) && $data->customer_id) {
    $quoteId = handleCustomerSession($oauthToken, $data->customer_id, $quoteId, $quoteCollectionFactory);
}

if ($quoteId) {
    try {
        $quote = $quoteRepository->get($quoteId);
        if (!$quote->getIsActive()) {
            $quoteId = handleInactiveQuote($quote, $quoteCollectionFactory, $quoteId);
        }
    } catch (\Exception $e) {
        $message = "Please Update App New Version"; // Handle error appropriately
    }
}

if ($quoteId) {
    $result = addProductsToQuote($quoteId,$objectManager,$data->cartItem ?? [], $quote, $productRepository, $result);
}

echo json_encode($result);

// Helper Functions
function validateAuthorization() {
    $message = '';
    $messageSuccess = true;
    $accessToken = '';

    if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
        $accessToken = extractAccessToken($_SERVER['HTTP_AUTHORIZATION']);
        if (!$accessToken) {
            $message = "Authorization header is present but invalid";
            $messageSuccess = false;
        }
    } else {
        $message = "Authorization header is not present";
        $messageSuccess = false;
    }
    return [$message, $messageSuccess, $accessToken];
}

function extractAccessToken($authorizationHeader) {
    if (preg_match('/Bearer\s+(.*)$/i', $authorizationHeader, $matches)) {
        return $matches[1];
    }
    return null;
}

function logRequest($connection, $quoteId, $accessToken, $data) {
    $connection->insert('ahqa_app_cart_report', [
        'cart_id' => $quoteId,
        'quote_id' => $quoteId,
        'header_token' => $accessToken,
        'customer_id' => $data->customer_id ?? 0,
        'request_content' => json_encode($data),
        'created_at' => date('Y-m-d H:i:s'),
    ]);
}

function handleCustomerSession($oauthToken, $customerId, &$quoteId, $quoteCollectionFactory) {
    try {
        $token = $oauthToken->loadByToken($customerId);
        if ($token->getCustomerId()) {
            $customerId = $token->getCustomerId();
            $activeQuote = $quoteCollectionFactory->create()
                ->addFieldToFilter('customer_id', $customerId)
                ->addFieldToFilter('is_active', 1)
                ->addFieldToFilter('entity_id', ['neq' => $quoteId]) // Exclude current quote ID
                ->setPageSize(1)
                ->getFirstItem();

            if ($activeQuote->getId()) {
                return $activeQuote->getId(); // Update quoteId
            }
        }
    } catch (\Exception $e) {
        return false; // Session expired or error
    }
    return true; // Session is active
}

function handleInactiveQuote($quote, $quoteCollectionFactory, $quoteId) {
    $customerId = $quote->getCustomerId();
    if ($customerId) {
        $activeQuote = $quoteCollectionFactory->create()
            ->addFieldToFilter('customer_id', $customerId)
            ->addFieldToFilter('is_active', 1)
            ->addFieldToFilter('entity_id', ['neq' => $quoteId]) // Exclude current quote ID
            ->setPageSize(1)
            ->getFirstItem();

        if ($activeQuote->getId()) {
            return $activeQuote->getId();
        }
    }
    return $quoteId; // No action needed
}

function addProductsToQuote($quoteId,$objectManager,$cartItems, $quote, $productRepository, $result) {
    $itemSku = [];
    $message = '';
    $messageSuccess = true;
    $totalAmount = $quote->getSubtotal();

    foreach ($cartItems as $itemData) {
        $sku = $itemData->sku;
        $qty = (int)$itemData->qty;
        $stockItem = $objectManager->create(\Magento\CatalogInventory\Api\StockRegistryInterface::class)->getStockItemBySku($sku);

        if (!$stockItem->getIsInStock() || $qty > $stockItem->getQty()) {
            $itemSku[$sku] = 'Out Of Stock';
            $messageSuccess = false;
            continue;
        }

        // Check for min and max sale qty
        if ($qty > $stockItem->getMaxSaleQty() || $qty < $stockItem->getMinSaleQty()) {
            $itemSku[$sku] = "Qty out of allowed range.";
            $messageSuccess = false;
            continue;
        }

        try {
            $product = $productRepository->get($sku);
            $quote->addProduct($product, $qty);
            $quote->collectTotals();
            $totalAmount = $quote->getSubtotal();
            $quote->save();
        } catch (\Exception $e) {
            $itemSku[$sku] = $e->getMessage();
            $messageSuccess = false;
        }
    }
    $result['quote_id'] = $quoteId;
    $result['subtotal'] = $totalAmount;
    $result['outofstock'] = $itemSku;
    $result['message'] = $message;
    $result['success'] = $messageSuccess;

    return $result;
}