<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Order;

use Gls\GlsPoland\DataProvider\ParcelShopDataProvider;
use Gls\GlsPoland\Entity\OrderParcelShop;
use Gls\GlsPoland\Entity\ShopDeliveryCarrier;
use Gls\GlsPoland\PrestaShop\Checkout\Presenter\ParcelShopAddressPresenter;
use Gls\GlsPoland\PrestaShop\Helper\CarrierFinder;
use Gls\GlsPoland\Repository\CheckoutSessionRepository;
use Gls\GlsPoland\Repository\OrderParcelShopRepository;

final class ParcelShopDetailsProvider
{
    private $carrierFinder;
    private $sessionRepository;
    private $orderParcelShopRepository;
    private $dataProvider;
    private $presenter;

    public function __construct(
        CarrierFinder $carrierFinder,
        CheckoutSessionRepository $sessionRepository,
        OrderParcelShopRepository $orderParcelShopRepository,
        ParcelShopDataProvider $dataProvider,
        ParcelShopAddressPresenter $presenter
    ) {
        $this->carrierFinder = $carrierFinder;
        $this->sessionRepository = $sessionRepository;
        $this->orderParcelShopRepository = $orderParcelShopRepository;
        $this->dataProvider = $dataProvider;
        $this->presenter = $presenter;
    }

    public function getForOrder(\Order $order): ?array
    {
        if (null !== $stored = $this->orderParcelShopRepository->find((int) $order->id)) {
            return $this->presentStoredParcelShop($stored);
        }

        $carrier = $this->carrierFinder->findOneByCarrierId((int) $order->id_carrier);

        if (!$carrier instanceof ShopDeliveryCarrier) {
            return null;
        }

        $checkoutSession = $this->sessionRepository->find((int) $order->id_cart);
        if (null === $checkoutSession) {
            return null;
        }

        $parcelShopId = $checkoutSession->getParcelShopId($carrier->getId()->getValue());
        if (null === $parcelShopId) {
            $parcelShopId = $checkoutSession->getParcelShopId((int) $order->id_carrier);
        }
        if (null === $parcelShopId) {
            return null;
        }

        $parcelShop = $this->dataProvider->getParcelShop($parcelShopId);
        if (null === $parcelShop) {
            return null;
        }

        $entity = new OrderParcelShop((int) $order->id, $parcelShop);
        $this->orderParcelShopRepository->add($entity);

        return [
            'id' => $parcelShopId,
            'name' => trim(sprintf('%s %s %s', $parcelShop->getName1(), $parcelShop->getName2(), $parcelShop->getName3())),
            'address' => $this->presenter->present($parcelShop),
        ];
    }

    private function presentStoredParcelShop(OrderParcelShop $parcelShop): array
    {
        $addressParts = array_filter([
            $parcelShop->getStreet(),
            trim(sprintf('%s %s', $parcelShop->getPostalCode(), $parcelShop->getCity())),
        ]);

        return [
            'id' => $parcelShop->getParcelShopId(),
            'name' => $parcelShop->getName(),
            'address' => implode('<br/>', $addressParts),
        ];
    }
}
