<?php

namespace FiloBlu\Flow\Model;

use Exception;
use FiloBlu\Flow\Helper\LoggerProvider;
use Magento\Framework\Data\Collection\AbstractDb;
use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Model\Context;
use Magento\Framework\Model\ResourceModel\AbstractResource;
use Magento\Framework\Registry;
use stdClass;

/**
 * Class Channel
 * @package FiloBlu\Flow\Model
 * @method parse(Inboundflow $flow)
 * @method \FiloBlu\Flow\Model\Channel\Config getChannelConfig()
 */
class Channel extends AbstractModel
{
    /**
     * Channel constructor.
     * @param LoggerProvider $loggerProvider
     * @param Context $context
     * @param Registry $registry
     * @param AbstractResource|null $resource
     * @param AbstractDb|null $resourceCollection
     * @param array $data
     */
    public function __construct(
        LoggerProvider $loggerProvider,
        Context $context,
        Registry $registry,
        AbstractResource $resource = null,
        AbstractDb $resourceCollection = null,
        array $data = []
    ) {
        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
        $this->_logger = $loggerProvider->getLogger();
    }

    /**
     * @noinspection MagicMethodsValidityInspection
     * @return void
     */
    public function _construct()
    {
        $this->_init(ResourceModel\Channel::class);
    }

    /**
     * @param int $id
     * @param null $field
     * @return $this|AbstractModel
     */
    public function load($id, $field = null)
    {
        parent::load($id, $field);

        $json = $this->getData('data');

        try {
            $object = json_decode($json, false);
        } catch (Exception $e) {
            $this->_logger->info($e->getMessage());
            return $this;
        }

        if (isset($object->config)) {
            $this->setData('config', (Array)$object->config);
        }

        if (isset($object->connector)) {
            $this->setData('connector', (Array)$object->connector);
        }

        if (isset($object->parser)) {
            $this->setData('parser', (Array)$object->parser);
        }

        if (isset($object->map)) {
            $this->setData('map', json_encode($object->map));
        }

        if (isset($object->use_map)) {
            $this->setData('use_map', $object->use_map ? 1 : 0);
        }

        return $this;
    }

    /**
     * @return AbstractModel
     * @throws Exception
     */
    public function save()
    {
        $data = $this->getData();

        $obj = new stdClass();

        if ($data['config']) {
            $obj->config = (object)$data['config'];
        }

        if ($data['connector']) {
            $obj->connector = (object)$data['connector'];
        }

        if ($data['parser']) {
            $obj->parser = (object)$data['parser'];
        }

        if ($data['map']) {
            $obj->map = json_decode($data['map'], JSON_FORCE_OBJECT);
        }

        if ($data['use_map']) {
            $obj->use_map = $data['use_map'];
        }

        $error = json_last_error();

        if ($error) {
            throw new Exception('No valid json map');
        }

        $obj_decoded = str_replace('null', '', json_encode($obj));

        $this->setData('data', $obj_decoded);

        return parent::save();
    }

    /**
     * @return bool
     */
    public function usesMap()
    {
        return (bool)$this->getData('use_map');
    }
}
