<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Hook\Admin;

use Gls\GlsPoland\Configuration\Api;
use Gls\GlsPoland\Controller\Admin\ConsignmentController;
use Gls\GlsPoland\PrestaShop\Grid\Filters\ConsignmentFilters;
use Gls\GlsPoland\PrestaShop\Helper\CarrierFinder;
use Gls\GlsPoland\PrestaShop\Hook\PrestaShopVersionAwareHookInterface;
use Gls\GlsPoland\PrestaShop\Hook\VersionRange;
use Gls\GlsPoland\PrestaShop\Order\ParcelShopDetailsProvider;
use PrestaShop\PrestaShop\Core\Grid\GridFactoryInterface;
use PrestaShop\PrestaShop\Core\Grid\Presenter\GridPresenterInterface;
use PrestaShopBundle\Security\Voter\PageVoter;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Twig\Environment;

final class DisplayAdminOrderMain implements PrestaShopVersionAwareHookInterface
{
    public const HOOK_NAME = 'displayAdminOrderMain';

    private $authorizationChecker;
    private $configuration;
    private $gridFactory;
    private $gridPresenter;
    private $parcelShopDetailsProvider;
    private $carrierFinder;
    private $twig;

    public function __construct(
        AuthorizationCheckerInterface $authorizationChecker,
        Api\ConfigurationInterface $configuration,
        GridFactoryInterface $gridFactory,
        GridPresenterInterface $gridPresenter,
        ParcelShopDetailsProvider $parcelShopDetailsProvider,
        CarrierFinder $carrierFinder,
        Environment $twig
    )
    {
        $this->authorizationChecker = $authorizationChecker;
        $this->configuration = $configuration;
        $this->gridFactory = $gridFactory;
        $this->gridPresenter = $gridPresenter;
        $this->parcelShopDetailsProvider = $parcelShopDetailsProvider;
        $this->carrierFinder = $carrierFinder;
        $this->twig = $twig;
    }

    public static function getVersionRange(): VersionRange
    {
        return new VersionRange('1.7.7');
    }

    /**
     * @param array{id_order?: int} $parameters
     */
    public function execute(array $parameters): string
    {
        if (0 >= $orderId = (int) ($parameters['id_order'] ?? null)) {
            return '';
        }

        $order = new \Order($orderId);
        if (!\Validate::isLoadedObject($order)) {
            return '';
        }

        $isGlsCarrier = null !== $this->carrierFinder->findOneByCarrierId((int) $order->id_carrier);
        $parcelShop = $this->parcelShopDetailsProvider->getForOrder($order);
        $canViewGrid = $this->authorizationChecker->isGranted(PageVoter::READ, ConsignmentController::TAB_NAME)
            || $this->authorizationChecker->isGranted(PageVoter::READ, 'AdminModules');

        $grid = null;
        $gridRecordsTotal = 0;
        if ($canViewGrid) {
            /** @var ConsignmentFilters $filters */
            $filters = ConsignmentFilters::buildDefaults();
            $filters->addFilter([
                'id_order' => $orderId,
                'sandbox' => $this->configuration->isSandboxEnabled(),
            ]);

            $grid = $this->gridFactory->getGrid($filters);
            $gridRecordsTotal = $grid->getData()->getRecordsTotal();
        }

        if (!$isGlsCarrier && null === $parcelShop && (null === $grid || 0 >= $gridRecordsTotal)) {
            return '';
        }

        $canCreate = $canViewGrid
            && $isGlsCarrier
            && (
                $this->authorizationChecker->isGranted(PageVoter::CREATE, ConsignmentController::TAB_NAME)
                || $this->authorizationChecker->isGranted(PageVoter::UPDATE, 'AdminModules')
            );

        return $this->twig->render('@Modules/glspoland/views/templates/hook/admin_order_main.html.twig', [
            'can_create' => $canCreate,
            'can_view_grid' => $canViewGrid,
            'debug_enabled' => defined('_PS_MODE_DEV_') && _PS_MODE_DEV_,
            'debug_button_visible' => $canCreate,
            'debug_grid_records_total' => $gridRecordsTotal,
            'debug_has_parcel_shop' => null !== $parcelShop,
            'order_id' => $orderId,
            'parcel_shop' => $parcelShop,
            'grid' => null === $grid ? null : $this->gridPresenter->present($grid),
        ]);
    }
}
