<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Grid\DataFactory;

use Gls\GlsPoland\AdePlus\Services\Services;
use Gls\GlsPoland\Carrier\CarrierType;
use Gls\GlsPoland\Carrier\ParcelShopType;
use Gls\GlsPoland\Translation\TranslatorAwareTrait;
use PrestaShop\PrestaShop\Core\Grid\Data\Factory\DoctrineGridDataFactory;
use PrestaShop\PrestaShop\Core\Grid\Data\Factory\GridDataFactoryInterface;
use PrestaShop\PrestaShop\Core\Grid\Data\GridData;
use PrestaShop\PrestaShop\Core\Grid\Data\GridDataInterface;
use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection;
use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollectionInterface;
use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface;

final class CarrierGridDataFactory implements GridDataFactoryInterface
{
    use TranslatorAwareTrait;

    private $dataFactory;

    public function __construct(DoctrineGridDataFactory $dataFactory)
    {
        $this->dataFactory = $dataFactory;
    }

    public function getData(SearchCriteriaInterface $searchCriteria): GridDataInterface
    {
        $data = $this->dataFactory->getData($searchCriteria);

        return new GridData(
            $this->modifyRecords($data->getRecords()->all()),
            $data->getRecordsTotal(),
            $data->getQuery()
        );
    }

    private function modifyRecords(array $records): RecordCollectionInterface
    {
        $typeLabels = [
            CarrierType::COURIER => $this->getTranslator()->trans('Courier', [], 'Modules.Glspoland.Carrier'),
            CarrierType::SHOP_DELIVERY => $this->getTranslator()->trans('Parcel shop delivery', [], 'Modules.Glspoland.Carrier'),
        ];
        $parcelShopTypeLabels = [
            null => $this->getTranslator()->trans('All GLS locations', [], 'Modules.Glspoland.Carrier'),
            '' => $this->getTranslator()->trans('All GLS locations', [], 'Modules.Glspoland.Carrier'),
            ParcelShopType::APM => $this->getTranslator()->trans('Parcel lockers', [], 'Modules.Glspoland.Carrier'),
            ParcelShopType::PUDO => $this->getTranslator()->trans('Pickup and drop-off points', [], 'Modules.Glspoland.Carrier'),
        ];

        foreach ($records as &$record) {
            $services = iterator_to_array($this->getServices($record));
            $record['services'] = [] === $services ? '--' : implode(', ', $services);
            $record['parcelshop_type'] = CarrierType::SHOP_DELIVERY === $record['type']
                ? ($parcelShopTypeLabels[$record['parcelshop_type'] ?? null] ?? $record['parcelshop_type'])
                : '--';
            $record['type'] = $typeLabels[$record['type']] ?? $record['type'];
            $record['countries'] = str_replace(',', ', ', $record['countries']);
        }

        return new RecordCollection($records);
    }

    private function getServices(array $record): \Generator
    {
        if (CarrierType::COURIER !== $record['type']) {
            return;
        }

        if ($record['cash_on_delivery']) {
            yield Services::CASH_ON_DELIVERY;
        }

        if ($record['document_return']) {
            yield Services::DOCUMENT_RETURN;
        }

        if ($record['saturday_delivery']) {
            yield Services::SATURDAY_DELIVERY;
        }

        if ($record['delivery_before_10']) {
            yield Services::DELIVERY_BEFORE_10;
        } elseif ($record['delivery_before_12']) {
            yield Services::DELIVERY_BEFORE_12;
        }
    }
}
