<?php declare(strict_types=1);

namespace Newland\Toubiz\Sync\Neos\Command\Task;

use Newland\Toubiz\Api\ObjectAdapter\ArticleAdapterInterface;
use Newland\Toubiz\Api\ObjectAdapter\Concern\ArticleConstants;
use Newland\Toubiz\Api\Service\Toubiz\Legacy\TourApiService;
use Newland\Toubiz\Sync\Neos\Command\Helper\ApiServiceHelper;
use Newland\Toubiz\Sync\Neos\Command\Helper\ConfigurationHelper;
use Neos\Flow\Annotations as Flow;
use Newland\Toubiz\Sync\Neos\Domain\Repository\ArticleRepository;
use Newland\Toubiz\Sync\Neos\Importer\ArticleImporter;
use Newland\Toubiz\Sync\Neos\Service\UuidPredictionService;

class SynchronizeToursFromLegacyToubiz implements SynchronizationTask, DeletesOld
{

    /**
     * @var ApiServiceHelper
     * @Flow\Inject()
     */
    protected $apiServiceHelper;

    /** @var int */
    protected $processed = 0;

    /** @var string[] */
    protected $ids = [];

    /**
     * @var ArticleRepository
     * @Flow\Inject()
     */
    protected $articleRepository;


    public function name(): string
    {
        return 'ToubizLegacy: tours';
    }

    public function configurations(ConfigurationHelper $configurationHelper): \Generator
    {
        $configuration = $configurationHelper->getConfigurationForService('Toubiz/Legacy/TourApi');
        if (!$configuration) {
            return;
        }

        foreach ($configuration['clients'] ?? [] as $clientConfig) {
            foreach ($clientConfig['languages'] ?? $configuration['languages'] ?? [ 'de' ] as $language) {
                $clientConfig['language'] = $language;
                yield $configurationHelper->mergeWithDefaults($clientConfig);
            }
        }
    }

    public function synchronize(
        array $configuration,
        \Closure $errorHandlerWrapper,
        \Closure $onProgress
    ): SynchronizationResult {

        /** @var TourApiService $service */
        $service = $this->apiServiceHelper->initializeApiServiceWithCommonConfigurationOptions(
            'Toubiz/Legacy/TourApi',
            $configuration
        );

        $uuidPredictionService = $this->uuidPredictionService(
            (string) $configuration['client'],
            (string) $configuration['language']
        );


        $this->ids = [];
        $this->processed = 0;
        $result = $service->fetchTours(
            $errorHandlerWrapper(
                function (
                    ArticleAdapterInterface $adapter,
                    ?int $total
                ) use (
                    $onProgress,
                    $configuration,
                    $uuidPredictionService
                ) {
                    $importer = new ArticleImporter();
                    $importer->setLanguage((string) $configuration['language']);
                    $importer->setClient((string) $configuration['client']);
                    $importer->setUuidPredictionService($uuidPredictionService);
                    $imported = $importer->import($adapter);
                    if ($imported) {
                        $this->ids[] = (string) $imported->getPersistenceObjectIdentifier();
                        $onProgress(++$this->processed, $total);
                    }
                }
            )
        );

        return SynchronizationResult::fromServiceResult($result, $this->ids);
    }

    public function deleteOld(SynchronizationResult $result, array $configuration, \Closure $onProgress): void
    {
        $this->articleRepository->removeBasedOnSynchronizationResult(
            $result,
            ArticleConstants::TYPE_TOUR,
            (string) $configuration['client'],
            (string) $configuration['language'],
            $onProgress
        );
    }

    private function uuidPredictionService(string $client, string $language): UuidPredictionService
    {
        $uuidPredictionService = new UuidPredictionService();
        $uuidPredictionService->setDefaultProperties(
            [
                'client' => $client,
                'language' => $language,
                'mainType' => ArticleConstants::TYPE_ATTRACTION,
            ]
        );

        return $uuidPredictionService;
    }
}
