<?php

namespace FiloBlu\ActiveCampaign\Block\Adminhtml\System\Config;

use FiloBlu\ActiveCampaign\Api\FieldsRepositoryInterface;
use FiloBlu\ActiveCampaign\Helper\Data;
use Magento\Backend\Block\Template\Context;
use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\View\Element\Html\Select;

/**
 * Class AbstractConfig
 * @package FiloBlu\ActiveCampaign\Block\Adminhtml\System\Config
 */
class AbstractConfig extends AbstractFieldArray
{
    /**
     * @var string
     */
    protected $_template = 'FiloBlu_ActiveCampaign::system/config/form/field/array.phtml';

    /**
     * @var string
     */
    protected $id;

    /**
     * @var array
     */
    protected $exclude = [];

    /**
     * @var string
     */
    protected $type;

    /**
     * Custom Model
     */
    protected $model;

    /**
     * @var array
     */
    protected $additionalOptions = [];
    /**
     * @var Data
     */
    protected $helperData;
    /**
     * @var FieldsRepositoryInterface
     */
    protected $fieldsRepository;

    /**
     * @var ResourceConnection
     */
    private $resourceConnection;

    /**
     * AbstractConfig constructor.
     * @param Context $context
     * @param ResourceConnection $resourceConnection
     * @param FieldsRepositoryInterface $fieldsRepository
     * @param array $data
     */
    public function __construct(
        Context $context,
        ResourceConnection $resourceConnection,
        FieldsRepositoryInterface $fieldsRepository,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->resourceConnection = $resourceConnection;
        $this->fieldsRepository = $fieldsRepository;
    }

    /**
     * Prepare to render
     *
     * @return void
     * @throws LocalizedException
     */
    protected function _prepareToRender()
    {
        $customAttributes = $this->getAttributesToRender();
        $acAttributes = $this->getACFieldsToRender();
        array_unshift($customAttributes, ['value' => '', 'label' => __('-- Select an attribute --')]);

        $customAttributesBlock =
            $this->getLayout()
                ->createBlock(Select::class)
                ->setId($this->_getCellInputElementId('<%- _id %>', $this->id.'_magento_field'))
                ->setName($this->_getCellInputElementName($this->id.'_magento_field'))
                ->setClass('select')
                ->setOptions($customAttributes);

        $acAttributesBlock =
            $this->getLayout()
                ->createBlock(Select::class)
                ->setId($this->_getCellInputElementId('<%- _id %>', $this->id.'_activecampaign_field'))
                ->setName($this->_getCellInputElementName($this->id.'_activecampaign_field'))
                ->setClass('select')
                ->setOptions($acAttributes);

        $this->addColumn("{$this->id}", [
            'label' => __('Magento Field'),
            'renderer' => $customAttributesBlock,
            'style' => 'min-width:100px'
        ]);
        $this->addColumn("{$this->id}_ac", [
            'label' => __('Active Campaign Field'),
            'renderer' => $acAttributesBlock,
            'style' => 'min-width:200px'
        ]);

        $this->_addAfter = false;
        $this->_addButtonLabel = __('Add');
    }

    /**
     * Gets the attribute to render
     *
     * @return array
     */
    protected function getAttributesToRender()
    {
        $customOptions = [];

        if ($this->type == 'eav') {
            $attributes = $this->model->getAttributes();
            foreach ($attributes as $k => $v) {
                if (!in_array($k, $this->exclude)) {
                    $frontendLabel = $v->getFrontendLabel();
                    if (!$frontendLabel) {
                        $frontendLabel = ucwords(str_replace('_', ' ', $k));
                    }
                    $customOptions[$k] = ['value' => $k, 'label' => "{$k} ({$frontendLabel})" ];
                }
            }
        } elseif ($this->type == 'flat') {
            $connection = $this->resourceConnection->getConnection(ResourceConnection::DEFAULT_CONNECTION);
            $tableName = $this->model->getCollection()->getMainTable();
            $attributes = $connection->describeTable($tableName);
            foreach ($attributes as $k => $v) {
                if (!in_array($k, $this->exclude)) {
                    $frontendLabel = str_replace('_', ' ', ucwords($k));
                    $customOptions[$k] = ['value' => $k, 'label' =>  "{$k} ({$frontendLabel})" ];
                }
            }
        }

        if (count($this->additionalOptions)) {
            foreach ($this->additionalOptions as $option) {
                $customOptions[$option['value']] = $option;
            }
        }

        ksort($customOptions);

        return $customOptions;
    }

    /**
     * @return array
     */
    public function getACFieldsToRender() {
        $fieldsList = $this->fieldsRepository->getAll();
        $list = [];
        foreach ($fieldsList as $item) {
            $list[$item['ac_id']] = ['value' => $item['ac_id'], 'label' => $item['name'] ];
        }
        return $list;
    }

    /**
     * @param string $htmlString
     * @param boolean $escapeSingleQuote
     * @return string
     */
    public function escapeHtmlAttr($htmlString, $escapeSingleQuote = true)
    {
        try{
            return parent::escapeHtmlAttr($htmlString, $escapeSingleQuote);
        } catch(\Magento\Framework\Exception\LocalizedException $e) {
            return $this->escapeHtml($htmlString);
        }
    }

    /**
     * @param string $jsString
     * @return string
     */
    public function escapeJs($jsString)
    {
        try{

            return parent::escapeJs($jsString);
        } catch(\Magento\Framework\Exception\LocalizedException $e) {

            if ($jsString === '' || ctype_digit($jsString)) {
                return $jsString;
            }

            return preg_replace_callback(
                '/[^a-z0-9,\._]/iSu',
                function ($matches) {
                    $chr = $matches[0];
                    if (strlen($chr) != 1) {
                        $chr = mb_convert_encoding($chr, 'UTF-16BE', 'UTF-8');
                        $chr = ($chr === false) ? '' : $chr;
                    }

                    return sprintf('\\u%04s', strtoupper(bin2hex($chr)));
                },
                $jsString
            );
        }
    }

    /**
     * @return string
     */
    public function getAddButtonLabel()
    {
        return $this->_addButtonLabel;
    }
}