<?php

namespace App\Helper;


use App\Entity\Product;
use App\Entity\Stock;
use App\Entity\Warehouse;
use App\Repository\ProductRepository;
use App\Repository\StockRepository;
use App\Repository\WarehouseRepository;
use Psr\Log\LoggerInterface;
use Symfony\Component\Finder\Finder;

use  App\Helper\App\Helper\SplFileInfo;

class HiltesImport
{
    private $productRepository;
	private $stockRepository;
    private $warehouseRepository;
    private $logger;
	protected $currentDirPath;
	protected $cachedWarehouseIds;
	private $cachedProdIds;
	private $cachedStockIds;
	protected $arrData = array();

	public function __construct(ProductRepository $productRepository,WarehouseRepository $warehouseRepository,StockRepository $stockRepository, LoggerInterface $logger)
	{
        $this->productRepository = $productRepository;
        $this->warehouseRepository = $warehouseRepository;
		$this->stockRepository = $stockRepository;
        $this->logger = $logger;

		$this->currentDirPath = getcwd();
	}


    /**
     * @return array|void
     */
	public function startImport($delta = false)
	{
		#*** Holt alle Dateien
		if($this->getFiles($delta)){
			#*** Holt alle Stocks und setzt ein Array **************
			$this->getStocks();
            $count = 0;
			if(!empty($this->arrData['orgFiles']['data']) && count($this->arrData['orgFiles']['data'])){
				foreach ($this->arrData['orgFiles']['data'] as $file) {

					if(is_file($file['realPath'])){
						$count += $this->loadFiles($file['realPath'],$file['fileSize']);
					}else{

						return array('error'=>1,'text'=>'Error is_file('.$file['realPath'].')');
					}
				}
                dump("Imported $count stocks");

			}else
				return array('success'=>1,'text'=>'No Files');
		}else
			return array('error'=>1,'text'=>'Error in getFiles or no file WS.FERTIG');
	}

    /**
     * @return bool
     */
	protected function getFiles($delta = false)
	{
		$finder = Finder::create();
		$finder
			->in($this->currentDirPath.'/hiltes/h2c/')
			->depth(0);

        if($delta) {
            $finder->name('/_D/');
        }else{
            $finder->notName('/_D/');
        }

		if ($finder->hasResults()) {
            #dump($finder);
			foreach ($finder as $file) {
                if($file->getExtension() != 'Ende') {
                    //prüfen ob Ende Datei vorhanden ist
                    if(file_exists($this->currentDirPath.'/hiltes/h2c/'.$file->getRelativePathname().'.Ende')) {
                        $this->arrData['orgFiles']['data'][] = array(
                            'realPath'	=> $file->getRealPath(),
                            'fileSize'	=> $file->getFileInfo()->getSize(),
                            'onlyFileName'	=> $file->getRelativePathname(),
                        );
                    }
                }
			}
		}else{
			return false;
		}

        return true;
	}
	protected function getStocks()
	{
		$r = $this->stockRepository->findAll();
		foreach ($r as $v) {
			$this->cachedStockIds[$v->getProductId()][$v->getWarehouse()->getId()] = $v;
		}
		#dd($this->cachedStockIds);
	}

    /**
     * @param $srcFile
     * @param $size
     * @return int
     */
	protected function loadFiles($srcFile,$size)
	{
		#*** Check File ****
		#dd($srcFile);
		$file = new \SplFileObject($srcFile);
        #dump($file->getRealPath());

        $this->logger->info('Starte Import von ' . $file->getRealPath());
		dump('Starte Import von ' . $file->getRealPath());
		$c = 0;
		while (!$file->eof()) {

//            #*** Convertiert die Zeile in UTF8
//            $data = iconv('ISO-8859-1','UTF-8',$file->fgets());
//
//            #*** Überspringt die erste Zeile
//            if($c == 0){
//                $c++;
//                continue;
//            }

            #*** Speichert die Zeile
			$this->switchSaveData($this->splitLine($file->fgets()));
            $c++;

		}

        //unlink($file->getRealPath());

        dump($c . ' Datensätze importiert');
        return $c;
	}
	protected function splitLine($str){
		return str_getcsv($str,';','"');
	}

	/**
	 * Hier wird festgelegt wo und wie die Zeile gespeichert wird
	 *
	 * @param array $arr
	 * @return void
	 */
	protected function switchSaveData(array $arr){
		if(!empty($arr[0])){
			#*** Leerzeichen löschen bei den einzelnen Einträgen **********
			$this->trimArray($arr);
			#***
            $this->saveData($arr);

		}
	}
	protected function trimArray(Array &$arr){
		foreach ($arr as $k=>$v) {
			$arr[$k] = trim($v);
		}
	}


    /**
     * @param array $arr
     * @return void
     */
	protected function saveData(Array $arr){
		//dump($arr);
		#*** Speichert und/oder Holt WareHouse ab
		$wareHouse = $this->checkWareHouseName($arr[3]);

		#*** PRodukt wird angelegt oder geholt ****
		#filiale;etikettnr;menge;
        $gtin  = $this->checkProduct(substr($arr[0],1));
		#*** Ermitteln ob schon ein ID vorhanden für ProdId und WareHouseId
		if(!empty($wareHouse) && !empty($this->cachedStockIds[$gtin][$wareHouse->getId()])){
			$stock = $this->cachedStockIds[$gtin][$wareHouse->getId()];
		}else{
        	$stock = new Stock();
	        $stock->setProductId($gtin);
    	    $stock->setWarehouse($wareHouse);
		}
		//dd('CHCEK');
        $stock->setInstock((int)$arr[1]/100);
        #$stock->setWarehouseId($wareHouseId);
		//dump($stock);
		$this->stockRepository->save($stock,true);
	}

    /**
     * @param string $wareHouseName
     * @return Warehouse|false|int|mixed|null
     */
	private function checkWareHouseName(string $wareHouseName){

        $wareHouseName = ltrim($wareHouseName,0);
		#*** WEnn keine geCached Id Vorhanden
		if(empty($this->cachedWarehouseIds[$wareHouseName])){
			#*** Check
			$warehouse2 = $this->warehouseRepository->findOneBy(['id'=> (int)$wareHouseName]);
			if(empty($warehouse2)){
				$warehouse = new Warehouse();
				$warehouse->setId((int)$wareHouseName);
				$warehouse->setName($wareHouseName);
				#
                $this->warehouseRepository->save($warehouse,true);

                $this->cachedWarehouseIds[$wareHouseName] = $warehouse;
				#*****************
				#$warehouse2 = $this->warehouseRepository->findOneBy(['id'=> (int)$wareHouseName]);
				#dump($warehouse2);
			}else{
                $this->cachedWarehouseIds[$wareHouseName] = $warehouse2;
            }

		}
		if(!empty($this->cachedWarehouseIds[$wareHouseName]))
			return $this->cachedWarehouseIds[$wareHouseName];
		return false;
	}

    /**
     * @param string $gtin
     * @return false|int|mixed|null
     */
	private function checkProduct(string $gtin){
		#*** WEnn keine geCached Id Vorhanden
		if(empty($this->cachedProdIds[$gtin])){
			#*** Check
            //dump($gtin);
			$prod2 = $this->productRepository->findOneBy(['gtin'=> $gtin]);
			//dump($prod2);
			if(empty($prod2)){
				$prod = new Product();
				$prod->setGtin($gtin);
//				$prod->setModellNr($modellNr);
//				$prod->setModellBez($modellBez);
//				$prod->setShopwareId("");
				#
                $this->cachedProdIds[$gtin] = $this->productRepository->save($prod,true);
				#*****************
				//$prod2 = $this->productRepository->findOneBy(['gtin'=> $gtin]);
				#dump($warehouse2);
			}else{
                $this->cachedProdIds[$gtin] = $prod2->getId();
            }

		}
		if(!empty($this->cachedProdIds[$gtin]))
			return $this->cachedProdIds[$gtin];
		return false;
	}
}