<?php

namespace common\logic\Order\Order\Service;

use common\logic\AbstractManager;
use common\logic\Document\DeliveryNote\Model\DeliveryNote;
use common\logic\Document\DeliveryNote\Repository\DeliveryNoteRepository;
use common\logic\Document\DeliveryNote\Service\DeliveryNoteBuilder;
use common\logic\Document\Document\Service\DocumentManager;
use common\logic\Document\Document\Service\DocumentSolver;
use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Repository\OrderRepository;
use yii\base\Exception;

class OrderDocumentManager extends AbstractManager
{
    protected OrderSolver $orderSolver;
    protected OrderRepository $orderRepository;
    protected DocumentSolver $documentSolver;
    protected DeliveryNoteRepository $deliveryNoteRepository;
    protected DeliveryNoteBuilder $deliveryNoteBuilder;
    protected DocumentManager $documentManager;

    public function loadDependencies(): void
    {
        $this->orderSolver = $this->loadService(OrderSolver::class);
        $this->orderRepository = $this->loadService(OrderRepository::class);
        $this->documentSolver = $this->loadService(DocumentSolver::class);
        $this->deliveryNoteRepository = $this->loadService(DeliveryNoteRepository::class);
        $this->deliveryNoteBuilder = $this->loadService(DeliveryNoteBuilder::class);
        $this->documentManager = $this->loadService(DocumentManager::class);
    }

    public function generateDeliveryNoteForPointSale(array $idOrders = []): ?DeliveryNote
    {
        reset($idOrders);
        $firstOrder = $this->orderRepository->findOneOrderById((int)$idOrders[key($idOrders)]);
        $ordersArray = Order::searchAll(['id' => $idOrders,]);
        $deliveryNote = $this->deliveryNoteRepository->getOneDeliveryNoteExistingFromOrders($ordersArray);
        $deliveryNote = $this->deliveryNoteBuilder->deleteDeliveryNoteIfStatusDraft($deliveryNote);

        if ($deliveryNote && $this->documentSolver->isStatusValid($deliveryNote)) {
            throw new Exception("Vous ne pouvez pas modifier un bon de livraison déjà validé.");
        }

        if(!$deliveryNote && $firstOrder && !$firstOrder->pointSale->id_user) {
            throw new Exception("Vous devez définir un contact de facturation pour ce point de vente.");
        }

        if ($firstOrder) {
            if (!$deliveryNote) {
                $deliveryNote = $this->deliveryNoteBuilder->createDeliveryNoteForPointSale(
                    $firstOrder->pointSale,
                    $firstOrder->distribution,
                    $idOrders
                );
            }

            return $deliveryNote;
        }

        return null;
    }

    public function generateDeliveryNotesForUser(array $idOrders = []): void
    {
        foreach($idOrders as $idOrder) {
            $order = $this->orderRepository->findOneOrderById($idOrder);
            $this->generateDeliveryNoteForUser($order);
        }
    }

    public function generateDeliveryNoteForUser(Order $order = null): ?DeliveryNote
    {
        if ($order && $this->orderSolver->isOrderFromProducer($order) && $order->id_user) {
            return $this->deliveryNoteBuilder->createDeliveryNoteForOrder($order);
        }

        return null;
    }

    public function validateDeliveryNotes(array $idOrders = []): bool
    {
        if (count($idOrders) > 0) {
            $oneDeliveryNoteValidated = false;
            foreach ($idOrders as $idOrder) {
                $order = $this->orderRepository->findOneOrderById($idOrder);
                if ($this->orderSolver->isOrderFromProducer($order)) {
                    $deliveryNote = $this->deliveryNoteRepository->findOneDeliveryNoteById((int) $order->id_delivery_note);
                    if($deliveryNote) {
                        $this->documentManager->validateDocument($deliveryNote);
                        $oneDeliveryNoteValidated = true;
                    }
                }
            }

            return $oneDeliveryNoteValidated;
        }

        return false;
    }
}