<?php

declare(strict_types=1);

/*
 * This file is part of vonRotenberg WMFGO Cevisio Bundle.
 *
 * (c) vonRotenberg
 *
 * @license proprietary
 */

namespace vonRotenberg\WmfgoCevisioBundle\Cron;

use Contao\CoreBundle\Controller\AbstractController;
use Contao\Date;
use Contao\System;
use Doctrine\DBAL\Connection;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Serializer\Encoder\CsvEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
use vonRotenberg\ShopwareApiBundle\API\Shopware;
use vonRotenberg\ShopwareApiBundle\Helper\ShopwareMappings;
use vonRotenberg\WmfgoCevisioBundle\Model\Import\ProductModel;

class ShopwareImportProductsJob extends AbstractController
{
    /** @var LoggerInterface */
    private $logger;

    /** @var SerializerInterface */
    private $serializer;

    /** @var Shopware */
    private $shopware;

    /** @var ShopwareMappings */
    private $mappings;

    private $csvContext = [];

    /** @var Finder */
    private $finder;

    /** @var Connection */
    private $db;

    /**
     * Remote
     * @var Connection
     */
    private $rdb;

    public function __construct(Finder $finder, Shopware $shopware, ShopwareMappings $mappings, Connection $db, LoggerInterface $logger)
    {
        $this->finder = $finder;
        $this->db = $db;
        $this->logger = $logger;
        $this->shopware = $shopware;
        $this->mappings = $mappings;

        $encoder      = [new CsvEncoder()];
        $normalizer   = [new ObjectNormalizer()];
        $this->serializer = new Serializer($normalizer,$encoder);

        $this->csvContext = [
            'csv_delimiter' => ';',
            'csv_enclosure' => '"',
        ];
    }

    public function import(string $scope, ?SymfonyStyle &$io = null): void
    {
        $intCounter = 0;
        $isCli = false;
        if (strtolower($scope) == 'cli' && $io !== null) {
            $isCli = true;
        }
        $translator = System::getContainer()->get('translator');
        $translator->setLocale('de');
        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
        $srcDir = $projectDir.'/import/products';
        if (!file_exists($srcDir)) {
            mkdir($srcDir, 0777,true);
        }

        $Today = new Date();

        $importFiles = $this->finder->files()->in($srcDir)->name('*.csv');

        if (!$importFiles->count())
        {
            return;
        }

        foreach ($importFiles as $importFile) {
            $data = $this->serializer->decode($importFile->getContents(), 'csv',$this->csvContext);
            if ($isCli) $io->progressStart(count($data));
            foreach ($data as $row) {
                /** @var ProductModel $Product */
                $Product = $this->serializer->denormalize($row,ProductModel::class);

                $arrData = [
                    'productNumber' => $Product->getSku(),
                    'taxId' => '018e65c0485071508949c072f8dc18bd',
                    'stock' => 999999,
                    'name' => $Product->getName(),
                    'isCloseout' => true,
                    'purchaseUnit' => (float) $Product->getBaseprice(),
                    'referenceUnit' => 1,
                    'unitId' => $this->mappings->getUnitIdByName('Liter')
                ];

                if ($Product->getPublished() == '1' || $Product->getPublished() == '0') $arrData['active'] = (bool) $Product->getPublished() ;
                if ($Product->getEan()) $arrData['ean'] = $Product->getEan();
                if ($Product->getShipping_weight()) $arrData['weight'] = $Product->getShipping_weight();
                if ($Product->getBesonderheit()) $arrData['description'] = $Product->getBesonderheit();

                // Custom fields handling
                $arrCustomFields = [];
                if (($customFieldVal = $Product->GetJahrgang())) {
                    $arrCustomFields['custom_wine_attributes_jahrgang'] = $customFieldVal;
                }

                if (($customFieldVal = $Product->getAlkohol())) {
                    $arrCustomFields['custom_wine_attributes_alkohol'] = $customFieldVal;
                }

                if (($customFieldVal = $Product->getSaeure())) {
                    $arrCustomFields['custom_wine_attributes_saeure'] = $customFieldVal;
                }

                if (($customFieldVal = $Product->getrestzucker())) {
                    $arrCustomFields['custom_wine_attributes_restzucker'] = $customFieldVal;
                }

                if (($customFieldVal = $Product->getZusatz())) {
                    $arrCustomFields['custom_wine_attributes_zusatz'] = $customFieldVal;
                }

                if (($customFieldVal = $Product->getAllergene())) {
                    $arrCustomFields['custom_wine_attributes_allergene'] = $customFieldVal;
                }

                if (($customFieldVal = $Product->getTrinktemperatur())) {
                    $arrCustomFields['custom_wine_attributes_trinktemperatur'] = $customFieldVal;
                }

                if (($customFieldVal = $Product->getSpeiseempfehlung())) {
                    $arrCustomFields['custom_wine_attributes_speiseempfehlung'] = $customFieldVal;
                }

                if (stripos($Product->getErzeuger(),'weinmanufaktur')) {
                    $arrCustomFields['custom_wine_attributes_erzeuger'] = 'WMFGO';
                }

                if (stripos($Product->getAnbauregion(),'Baden')) {
                    $arrCustomFields['custom_wine_attributes_anbauregion'] = 'Baden';
                }

                if (stripos($Product->getUrsprungsland(),'weinmanufaktur')) {
                    $arrCustomFields['custom_wine_attributes_ursprungsland'] = 'DE';
                }

                if (count($arrCustomFields))
                {
                    $arrData['customFields'] = $arrCustomFields;
                }

                // Properties handling
                $arrProperties = [];
                $arrPropertyGroups = [];

                if (
                    ($propertyVal = $Product->getLage())
                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Einzellage')) !== null
                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
                {
                    $arrProperties[] = [
                        'id' => $propertyId,
                        'groupId' => $propertyGroupId,
                        'name' => $propertyVal
                    ];
                    $arrPropertyGroups[] = $propertyGroupId;
                }

                if (
                    ($propertyVal = $Product->getQualitaet())
                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Qualität')) !== null
                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
                {
                    $arrProperties[] = [
                        'id' => $propertyId,
                        'groupId' => $propertyGroupId,
                        'name' => $propertyVal
                    ];
                    $arrPropertyGroups[] = $propertyGroupId;
                }

                if (
                    ($propertyVal = $Product->getFarbe())
                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Farbe')) !== null
                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
                {
                    $arrProperties[] = [
                        'id' => $propertyId,
                        'groupId' => $propertyGroupId,
                        'name' => $propertyVal
                    ];
                    $arrPropertyGroups[] = $propertyGroupId;
                }

                if (
                    ($propertyVal = $Product->getGeschmack())
                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Geschmack')) !== null
                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
                {
                    $arrProperties[] = [
                        'id' => $propertyId,
                        'groupId' => $propertyGroupId,
                        'name' => $propertyVal
                    ];
                    $arrPropertyGroups[] = $propertyGroupId;
                }

                if (
                    ($propertyVal = $Product->getRebsorte())
                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Rebsorte')) !== null
                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
                {
                    $arrProperties[] = [
                        'id' => $propertyId,
                        'groupId' => $propertyGroupId,
                        'name' => $propertyVal
                    ];
                    $arrPropertyGroups[] = $propertyGroupId;
                }

                if (
                    ($propertyVal = $Product->getWeinlinie())
                    && ($propertyGroupId = $this->mappings->getPropertyGroupIdByName('Weinlinie')) !== null
                    && ($propertyId = $this->mappings->getPropertyIdByNameAndGroup($propertyVal,$propertyGroupId, true)) !== null)
                {
                    $arrProperties[] = [
                        'id' => $propertyId,
                        'groupId' => $propertyGroupId,
                        'name' => $propertyVal
                    ];
                    $arrPropertyGroups[] = $propertyGroupId;
                }

                if (count($arrProperties))
                {
                    $this->shopware->truncatePropertiesForProductBySku($Product->getSku(),$arrPropertyGroups);
                    $arrData['properties'] = $arrProperties;
                }

                // Price handling
                if (($price = $Product->getPreis())) {
                    $arrPrice = [
                        'currencyId' => $this->mappings->getCurrencyIdByName('Euro'),
                        'gross' => $price,
                        'net' => $price/119*100,
                        'linked' => true
                    ];

                    if (($listprice = $Product->getPreis_uvp())) {
                        $arrPrice['listPrice'] = [
                            'currencyId' => $this->mappings->getCurrencyIdByName('Euro'),
                            'gross' => $listprice,
                            'net' => $listprice/119*100,
                            'linked' => true
                        ];
                    } else {
                        $arrPrice['listPrice'] = [
                            'currencyId' => $this->mappings->getCurrencyIdByName('Euro'),
                            'gross' => 0,
                            'net' => 0,
                            'linked' => true
                        ];
                    }

                    $arrData['price'] = [$arrPrice];
                }


                if (!$this->shopware->addOrUpdateProductBySku($Product->getSku(), $arrData))
                {
                    if ($isCli) $io->error('Could not update/import Product ' . $Product->getSku());
                    dump($arrData);
                }

                if ($isCli)
                {
                    $io->progressAdvance();
                }
//                return;
            }
            if ($isCli) $io->progressFinish();
        }
    }
}