<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonPickwareMobile\Components\Decorators\ViisonPickwareERP;

use Shopware\Components\Model\ModelManager;
use Shopware\Models\Document\Document as DocumentType;
use Shopware\Models\Order\Document\Document as OrderDocument;
use Shopware\Models\Order\Order;
use Shopware\Plugins\ViisonPickwareERP\Components\Document\OrderDocumentCreation;
use Shopware\Plugins\ViisonPickwareERP\Components\Document\OrderDocumentCreationServiceDecoration;

class OrderDocumentCreationIdempotencyDecorator implements OrderDocumentCreation
{
    use OrderDocumentCreationServiceDecoration;

    /**
     * @var ModelManager
     */
    private $entityManager;

    /**
     * @param OrderDocumentCreation $decoratedService
     * @param ModelManager $entityManager
     */
    public function __construct(OrderDocumentCreation $decoratedService, $entityManager)
    {
        $this->decoratedService = $decoratedService;
        $this->entityManager = $entityManager;
    }

     /**
     * @inheritdoc
     */
    public function createOrderDocument(Order $order, DocumentType $documentType, array $documentConfig = [])
    {
        $shipmentGuid = $order->getAttribute()->getPickwareWmsShipmentGuid();
        if (!$shipmentGuid) {
            return $this->decoratedService->createOrderDocument($order, $documentType, $documentConfig);
        }

        // Check whether the order already contains a document of the same type and shipment GUID
        $builder = $this->entityManager->createQueryBuilder();
        $builder
            ->select('document')
            ->from(OrderDocument::class, 'document')
            ->leftJoin('document.attribute', 'documentAttribute')
            ->where('document.order = :order')
            ->andWhere('document.type = :documentType')
            ->andWhere('documentAttribute.pickwareWmsShipmentGuid = :shipmentGuid')
            ->setParameter('order', $order)
            ->setParameter('documentType', $documentType)
            ->setParameter('shipmentGuid', $shipmentGuid)
            ->setMaxResults(1);
        $document = $builder->getQuery()->getOneOrNullResult();
        if ($document) {
            return $document;
        }

        // Create a new document and assign it the shipment GUID
        $document = $this->decoratedService->createOrderDocument($order, $documentType, $documentConfig);
        $documentAttribute = $document->getAttribute();
        $documentAttribute->setPickwareWmsShipmentGuid($shipmentGuid);
        $this->entityManager->flush($documentAttribute);

        return $document;
    }
}
