<?php

namespace YSquare\Shipcloud\Application\Controller\Admin;

use Doctrine\DBAL\Query\QueryBuilder;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;

class AdminSettings
{
    public $sandboxMode = true;
    protected $sModule = 'ys_shipcloud';
    protected $defaultValueGroup;
    protected $aDbSettings = null;
    protected $aSettings = null;
    protected $queryBuilderFactory;

    public function __construct($defaultValueGroup)
    {
        $this->defaultValueGroup = $defaultValueGroup;

        $container = ContainerFactory::getInstance()->getContainer();
        $this->queryBuilderFactory = $container->get(QueryBuilderFactoryInterface::class);

        $this->sandboxMode = $this->getSettings('ENABLE_SANDBOX_MODUS') == "on";
    }

    /**
     * @param null $key
     * @param null $valueGroup
     * @return array|mixed
     */
    public function getSettings($key = null, $valueGroup = null)
    {
        $sValueGroup = $valueGroup ?? $this->defaultValueGroup;

        if (null === $this->aDbSettings) {
            $this->aDbSettings = [];
        }

        if (!$this->aDbSettings[$sValueGroup]) {
            /** @var QueryBuilder $queryBuilder */
            $queryBuilder = $this->queryBuilderFactory->create();

            $queryBuilder
                ->select('ysvarvalue')
                ->from('ysconfig')
                ->where('ysmodule=:module')
                ->andWhere('ysvarname=:varname')
                ->andWhere('OXSHOPID=:shop')
                ->setParameter('module', $this->sModule)
                ->setParameter('varname', $sValueGroup)
                ->setParameter('shop', Registry::getConfig()->getShopId());

            $results = $queryBuilder->execute()->fetchAll();

            $rows = [];
            # TODO validate
            foreach ($results as $result) {
                $rows[] = json_decode($result["ysvarvalue"], true);
            }

            if (sizeof($rows) == 1) {
                $this->aDbSettings[$sValueGroup] = $rows[0];
            } else {
                $this->aDbSettings[$sValueGroup] = $rows;
            }
        }

        if ($this->aDbSettings and $this->aDbSettings[$sValueGroup]) {
            if ($key) {
                if ($this->aDbSettings[$sValueGroup]['settings'] and
                    is_array($this->aDbSettings[$sValueGroup]['settings'])) {
                    return $this->aDbSettings[$sValueGroup]['settings'][$key];
                }
                return $this->aDbSettings[$sValueGroup][$key];
            } else {
                return $this->aDbSettings[$sValueGroup];
            }
        } else {
            return [];
        }
    }

    public function save($editValues)
    {
        $this->aSettings = [];
        $this->aSettings['settings'] = $editValues;

        $this->setSettings($this->aSettings);
    }

    public function setSettings($values, $valueGroup = null): bool
    {
        $sValueGroup = $valueGroup ?? $this->defaultValueGroup;

        $serializedArray = '';
        if (is_array($values)) {
            $serializedArray = json_encode($values);
        } elseif (is_string($values)) {
            $serializedArray = $values;
        }

        /** @var QueryBuilder $queryBuilder */
        $blDelete = $this->queryBuilderFactory->create()
            ->delete('ysconfig')
            ->where('ysmodule=:module')
            ->andWhere('ysvarname=:varname')
            ->andWhere('OXSHOPID=:shop')
            ->setParameters(
                [
                    "module"  => $this->sModule,
                    "varname" => $sValueGroup,
                    "shop"    => Registry::getConfig()->getShopId(),
                ]
            )
            ->execute();

        $blInsert = $this->queryBuilderFactory->create()
            ->insert('ysconfig')
            ->values(
                [
                    "oxid"       => ':oxid',
                    "oxshopid"   => ':shop',
                    "ysmodule"   => ':module',
                    "ysvarname"  => ':varname',
                    "ysvarvalue" => ':varvalue',
                ]
            )
            ->setParameters(
                [
                    "oxid"     => Registry::getUtilsObject()->generateUId(),
                    "shop"     => Registry::getConfig()->getShopId(),
                    "module"   => $this->sModule,
                    "varname"  => $sValueGroup,
                    "varvalue" => $serializedArray,
                ]
            )
            ->execute();

        // Force reload of settings
        $this->aDbSettings = null;
        $this->getSettings();

        return !$blDelete and !$blInsert;
    }

    public function loadValues()
    {
        if (null === $this->aSettings) {
            $this->aSettings = $this->getSettings();
        }

        return $this->aSettings['settings'];
    }
}
