<?php

namespace FiloBlu\Flow\Helper;

use DateTime;
use DateTimeZone;
use Exception;
use FiloBlu\Flow\Model\Inboundflow;
use FiloBlu\Flow\Model\Processor as FlowModelProcessor;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\App\Helper\AbstractHelper;
use FiloBlu\Flow\Model\InboundflowFactory;

/**
 * Class Flow
 * @package FiloBlu\Flow\Helper
 */
class Flow extends AbstractHelper
{

    /**
     * @var FlowModelProcessor
     */
    public $flowModelProcessor;
    /**
     * @var InboundflowFactory
     */
    protected $inboundFlowFactory;

    /**
     * Flow constructor.
     * @param FlowModelProcessor $flowModelProcessor
     * @param InboundflowFactory $inboundFlowFactory
     */
    public function __construct(
        FlowModelProcessor $flowModelProcessor,
        InboundflowFactory $inboundFlowFactory
    ){
        $this->flowModelProcessor = $flowModelProcessor;
        $this->inboundFlowFactory = $inboundFlowFactory;
    }

    /**
     * @param $channel_name
     * @param $array_of_data
     * @param $csv_header
     * @return false|string
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function generateCsvFromArray($channel_name, $array_of_data,$csv_header = null){

        if(count($array_of_data) === 0){
            return false;
        }

        if (!$csv_header){
            $csv_header = array_keys($array_of_data[0]);
        }

        $thisRunDate = new DateTime();
        $thisRunDate->setTimezone( new DateTimeZone('UTC') );
        $datenow = $thisRunDate->format('YmdHis');

        $channel = $this->getFlowChannel($channel_name);
        if (!$channel){
            throw new NoSuchEntityException();
        }
        $connector = $channel->getConnector();
        $connector_config = $connector->getConfig();
        $channel_config = $channel->getChannelConfig();
        $filename_regex = $connector_config['regex'];
        $filename = $this->getStringBetween($filename_regex, '#^', '_#')."_{$datenow}". '.csv';
        $directory = $connector->getLocalDir();

        $full_path = "{$directory}/{$filename}";

        $csv_separator = $channel_config->_mappedData['parser']['separator'];
        $csv_enclosure = $channel_config->_mappedData['parser']['delimiter'];

        $fp = fopen($full_path, 'w');

        fputcsv($fp, $csv_header,$csv_separator,$csv_enclosure);
        foreach ($array_of_data as $k => $v) {
            fputcsv($fp, $v,$csv_separator,$csv_enclosure);
        }
        fclose($fp);

        return $filename;
    }

    private function getStringBetween($string, $start, $end){
        $string = ' ' . $string;
        $ini = strpos($string, $start);
        if ($ini == 0) return '';
        $ini += strlen($start);
        $len = strpos($string, $end, $ini) - $ini;
        return substr($string, $ini, $len);
    }

    public function getFlowChannel($name){
        $this->flowModelProcessor->initConfig();
        $model = $this->flowModelProcessor->setChannels();
        $channels = $model->getChannels();
        if (isset($channels[$name])){
            return $channels[$name];
        }
        return false;
    }

    public function addFlowInboundRow($filename,$channelName){

        $channel = $this->getFlowChannel($channelName);

        $channelFlow = $channel->getConfig('flow');
        $channelType = $channel->getConfig('type');
        $channelPriority = $channel->getConfig('priority');

        $model = $this->inboundFlowFactory->create();
        $model->setName($filename);
        $model->setFlow($channelFlow);
        $model->setType($channelType);
        $model->setChannel($channelName);
        $model->setRetry(0);
        $model->setStatus(Inboundflow::STATUS_RECEIVED);
        $model->setPriority($channelPriority);
        try {
            $model->save();
        } catch (Exception $e) {
            // TODO: do something here
        }
    }

}
