<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Order;

use Gls\GlsPoland\Consignment\DTO\ServiceDetails;
use Gls\GlsPoland\Entity\ShopDeliveryCarrier;
use Gls\GlsPoland\Entity\CourierCarrier;
use Gls\GlsPoland\PrestaShop\Helper\CarrierFinder;
use Gls\GlsPoland\Repository\CheckoutSessionRepository;

final class ServiceDetailsFactory
{
    private $carrierFinder;
    private $checkoutSessionRepository;

    public function __construct(CarrierFinder $carrierFinder, CheckoutSessionRepository $checkoutSessionRepository)
    {
        $this->carrierFinder = $carrierFinder;
        $this->checkoutSessionRepository = $checkoutSessionRepository;
    }

    public function create(\Order $order): ServiceDetails
    {
        if (null === $carrier = $this->carrierFinder->findOneByCarrierId((int) $order->id_carrier)) {
            return new ServiceDetails();
        }

        return $carrier instanceof ShopDeliveryCarrier
            ? $this->getShopDeliveryServiceDetails($carrier, $order)
            : $this->getServiceDetails($carrier, $order);
    }

    private function getShopDeliveryServiceDetails(ShopDeliveryCarrier $carrier, \Order $order): ServiceDetails
    {
        $checkoutSession = $this->checkoutSessionRepository->find((int) $order->id_cart);
        $parcelShopId = $checkoutSession
            ? $checkoutSession->getParcelShopId($carrier->getId()->getValue())
            : null;

        return (new ServiceDetails())->setParcelShopId($parcelShopId ?? '');
    }

    private function getServiceDetails(CourierCarrier $carrier, \Order $order): ServiceDetails
    {
        $codAmount = $carrier->isCashOnDelivery()
            ? (float) $order->total_paid_tax_incl
            : null;

        return (new ServiceDetails())
            ->setCashOnDeliveryAmount($codAmount)
            ->setDocumentReturn($carrier->isDocumentReturn())
            ->setSaturdayDelivery($carrier->isSaturdayDelivery())
            ->setTimeDefiniteService($carrier->getTimeDefiniteService());
    }
}
