<?php
namespace ModulesGarden\Servers\OpenXchange\App\Libs\Product;
use ModulesGarden\Servers\OpenXchange\App\Enums\ControllerEnums;
use ModulesGarden\Servers\OpenXchange\App\Enums\ProductParams;
use ModulesGarden\Servers\OpenXchange\App\Enums\Size;
use ModulesGarden\Servers\OpenXchange\App\Enums\Zimbra;
use ModulesGarden\Servers\OpenXchange\App\Libs\Zimbra\Components\Api\Soap\Connection;
use ModulesGarden\Servers\OpenXchange\App\Libs\Zimbra\Components\Api\Soap\Repository\ClassOfServices;
use ModulesGarden\Servers\OpenXchange\App\Services\ConfigurableOptions\Helper\TypeConstans;
use ModulesGarden\Servers\OpenXchange\App\Services\ConfigurableOptions\Strategy\Types\ClassOfServicesOptions;
use ModulesGarden\Servers\OpenXchange\App\Traits\ConfigTrait;
use ModulesGarden\Servers\OpenXchange\App\Traits\ModuleConfigurationHandler;
use ModulesGarden\Servers\OpenXchange\Core\Models\Whmcs\Hosting;
use ModulesGarden\Servers\OpenXchange\Core\Models\Whmcs\HostingConfigOption;
use ModulesGarden\Servers\OpenXchange\App\Models\ProductConfiguration;
use ModulesGarden\Servers\OpenXchange\Core\Models\Whmcs\Server;

/**
 *
 * Created by PhpStorm.
 * User: Tomasz Bielecki ( tomasz.bi@modulesgarden.com )
 * Date: 11.09.19
 * Time: 12:26
 * Class ProductManager
 */
class ProductManager
{

    use ConfigTrait;
    use ModuleConfigurationHandler;
    /**
     *
     * @var array
     */
    protected $cos = [];

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

    /**
     * @var bool
     */
    protected $cosConfigOptionEnabled = false;
    /**
     * @var Hosting
     */
    protected $hosting = null;
    /**
     * @param $id
     * @return $this
     */
    public function loadByHostingId($id)
    {
        /**
         *
         * load hosting model
         */
        $this->hosting = Hosting::with('configOptions')->where('id', $id)->first();

        /**
         *
         * load product configuration
         */
        $this->loadById($this->hosting->packageid);

        /**
         *
         *
         * load config options (e.g class of services)
         */
        $this->loadConfigOptions($this->hosting->configOptions);

        /**
         *
         */
        return $this;
    }

    /**
     * @param $id
     * @return $this
     */
    public function loadById($id)
    {
        $config = ProductConfiguration::where('product_id', $id)->get();
        foreach ($config as $conf)
        {
            $this->set($conf->setting, $conf->value);
        }

        return $this;
    }

    /**
     * @return Hosting
     */
    public function getHosting()
    {
        return $this->hosting;
    }

    /**
     * @param $configOpt
     * @return $this
     */
    public function loadConfigOptions($configOpt)
    {
        /**
         * configurable options to config array
         */
        foreach ($configOpt as $opt)
        {
            /**
             *
             * continue if conf opt is hidden
             */
            if((bool) $opt->configOption->hidden === true)
            {
                continue;
            }

            if(!$opt->configOption->isLinkedToProduct($this->hosting->packageid))
            {
                continue;
            }
            /* @var $opt HostingConfigOption */
            $option = explode('|', $opt->configOption->optionname);

            if (false !== strpos( $option[0], ClassOfServicesOptions::COS_CONFIG_OPT_PREFIX))
            {
                $this->addCosConfigOpt($option[0], $opt->qty);
                continue;
            }

            /**
             * base setting
             */
            if ((int) $opt->configOption->optiontype === TypeConstans::QUANTITY)
            {
                $this->set($option[0], $opt->qty);
                continue;

            }
            elseif ((int) $opt->configOption->optiontype === TypeConstans::DROPDOWN)
            {
                /**
                 * selected class of services
                 */
                $name = explode('|', $opt->subOption->optionname);
                if($option[0] === 'cos')
                {
                    /**
                     * add to available cos list
                     */
                    $this->addCosConfigOpt($name[0], Size::UNLIMITED);
                }

                $this->set($option[0], $name[0]);
                continue;
            }
        }

        return $this;
    }

    /**
     * @param $cosName
     * @param int $quantity
     * @return $this
     */
    public function addCosConfigOpt($cosName, $quantity= 0)
    {
        $cosName = str_replace(ClassOfServicesOptions::COS_CONFIG_OPT_PREFIX,'',$cosName);
        $this->cos[$cosName] = $quantity;
        $this->configOptCosLimits[$cosName] = $quantity;
        $this->setCosConfigOptionEnabled(true);
        return $this;
    }

    /**
     * @return mixed
     */
    public function getZimbraConfiguration()
    {
        foreach($this->config as $name => $value)
        {
            if(false !== strpos($name, ProductParams::ZIMBRA_PREFIX_SETTINGS))
            {
                $tmp[$name] = $value;
            }
        }

        return $tmp;
    }

    

    /**
     * @return string|null
     */
    public function getServerUrl()
    {
        if($this->hosting)
        {
            $server = $this->hosting->server()->first();

            $hostname = $server->hostname ? $server->hostname : $server->ipaddress;

            $url = ($server->secure ? 'https://' : 'http://') . $hostname.($server->secure ? ':'.Zimbra::SECURE_PORT: ':'.Zimbra::PORT).'/';
            return $url;
        }
        return null;
    }

   

    /**
     * @return array
     */
    public function getConfigOptCosLimits()
    {
        return $this->configOptCosLimits;
    }

    /**
     * @param array $configOptCosLimits
     */
    public function setConfigOptCosLimits($configOptCosLimits)
    {
        $this->configOptCosLimits = $configOptCosLimits;
    }

    /**
     * @return bool
     */
    public function isCosConfigOptionEnabled()
    {
        return $this->cosConfigOptionEnabled;
    }

    /**
     * @param bool $cosConfigOptionEnabled
     */
    public function setCosConfigOptionEnabled($cosConfigOptionEnabled)
    {
        $this->cosConfigOptionEnabled = $cosConfigOptionEnabled;
    }



}