<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Installer;

use Gls\GlsPoland\Carrier\DTO\AdditionalServices;
use Gls\GlsPoland\Entity\Carrier;
use Gls\GlsPoland\PrestaShop\Message\CreateShopDeliveryCarrierCommand;
use Gls\GlsPoland\PrestaShop\Message\CreateCourierCarrierCommand;
use Gls\GlsPoland\PrestaShop\Message\DeleteCarrierCommand;
use Gls\GlsPoland\Repository\CarrierRepository;
use Gls\GlsPoland\Translation\TranslatorAwareTrait;
use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface;

final class CarrierInstaller implements InstallerInterface, UninstallerInterface
{
    use TranslatorAwareTrait;

    private $bus;
    private $carrierRepository;

    public function __construct(CommandBusInterface $bus, CarrierRepository $carrierRepository)
    {
        $this->bus = $bus;
        $this->carrierRepository = $carrierRepository;
    }

    public function install(\Module $module): void
    {
        if ([] !== $this->carrierRepository->findAll()) {
            return;
        }

        try {
            $this->createStandardCarrier();
            $this->createCashOnDeliveryCarrier();
            $this->createShopDeliveryCarrier();
        } catch (\Exception $e) {
            throw new InstallerException($this->getTranslator()->trans('Could not create module\'s carriers.', [], 'Modules.Glspoland.Installer'), 0, $e);
        }
    }

    public function uninstall(\Module $module, bool $isReset): void
    {
        if ($isReset) {
            return;
        }

        foreach ($this->carrierRepository->findAll() as $carrier) {
            try {
                $this->deleteCarrier($carrier);
            } catch (\Exception $e) {
                throw new InstallerException($this->getTranslator()->trans('Could not delete carrier (ID: #id#).', ['#id' => $carrier->getId()->getValue()], 'Modules.Glspoland.Installer'), 0, $e);
            }
        }
    }

    private function deleteCarrier(Carrier $carrier): void
    {
        $command = new DeleteCarrierCommand($carrier->getId()->getValue());

        $this->bus->handle($command);
    }

    private function createStandardCarrier(): void
    {
        $command = new CreateCourierCarrierCommand(
            $this->getTranslator()->trans('GLS Courier', [], 'Modules.Glspoland.Carrier'),
            ['PL']
        );

        $this->bus->handle($command);
    }

    private function createCashOnDeliveryCarrier(): void
    {
        $command = new CreateCourierCarrierCommand(
            sprintf(
                '%s - %s',
                $this->getTranslator()->trans('GLS Courier', [], 'Modules.Glspoland.Carrier'),
                $this->getTranslator()->trans('Cash on Delivery', [], 'Modules.Glspoland.Service')
            ),
            ['PL'],
            new AdditionalServices(true)
        );

        $this->bus->handle($command);
    }

    private function createShopDeliveryCarrier(): void
    {
        $command = new CreateShopDeliveryCarrierCommand(
            $this->getTranslator()->trans('GLS ParcelShop', [], 'Modules.Glspoland.Carrier'),
            ['PL']
        );

        $this->bus->handle($command);
    }
}
