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

/**
 *
 * Created by PhpStorm.
 * User: ThurData
 * 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 getKerioConfiguration()
    {
        foreach($this->config as $name => $value)
        {
            if(false !== strpos($name, ProductParams::KERIO_PREFIX_SETTINGS))
            {
                $tmp[$name] = $value;
            }
        }

        return $tmp;
    }

    /**
     * @return mixed
     */
    public function getSettingCos()
    {
        /**
         *
         * if type is `cosQuota` return saved class of services list
         */
        if($this->get('cos_name') === ClassOfServices::CLASS_OF_SERVICE_QUOTA)
        {

            /**
             *
             * return cos from config opt or decoded from database
             */
            return $this->cos ? $this->cos : json_decode($this->get('cos'), true);
        }

        /**
         *
         * if type is `kerioConfigurableOptions` return choosed cos id
         */
        if($this->get('cos_name') === ClassOfServices::KERIO_CONFIG_OPTIONS)
        {
            return $this->cos;
        }

        /**
         *
         * return cos name if is other type
         */
        if($this->get('cos_name') !== ClassOfServices::CUSTOM_KERIO)
        {
            return $this->get('cos_name');
        }

        return null;
    }

    /**
     *
     * is available controller actions
     * @param $controller
     * @return bool
     */
    public function isControllerAccessible($controller)
    {
        return $this->get($controller) === ProductParams::SWITCHER_ENABLED;
    }

    /**
     * @param $name
     * @return bool
     */
    public function isSidebarEnabled($name)
    {
        switch ($name)
        {
            case 'emailAccount':
                $controller = ControllerEnums::EMAIL_ACCOUNT_PAGE;
                break;
            case 'emailAlias':
                $controller = ControllerEnums::EMAIL_ALIAS_PAGE;
                break;
            case 'ressource':
                $controller = ControllerEnums::RESSOURCE_PAGE;
                break;
            case 'distributionList':
                $controller = ControllerEnums::DISTRIBUTION_MAIL_PAGE;
                break;
            case 'domainAlias':
                $controller = ControllerEnums::DOMAIN_ALIAS_PAGE;
                break;
            case 'setting':
                $controller = ControllerEnums::SETTING_PAGE;
                break;
            case 'goWebmail':
                $controller = ControllerEnums::WEBMAIL_PAGE;
                break;

        }
        return $this->isActionAccessible($controller);
    }

    /**
     *
     * @param $action
     * @return bool
     */
    public function isActionAccessible($action)
    {
        return $this->get($action) === ProductParams::SWITCHER_ENABLED;
    }

    /**
     * @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 ? ':'.Kerio::SECURE_PORT: ':'.Kerio::PORT).'/';
            return $url;
        }
        return null;
    }

    /**
     * @return string|null
     */
    public function getClientUrl()
    {
        if($this->hosting)
        {

            /**
             *
             * load server
             */
            $server = $this->hosting->server()->first();

            /**
             * set hostname if exist or IP address
             */
            $hostname = $server->hostname ? $server->hostname : $server->ipaddress;

            /**
             *
             * load port from configuration or set default port
             */
            $port = $server->secure === 'on' ? $this->loadModuleData()->getAll()['clienPortSecure'] : $this->loadModuleData()->getAll()['clienPort'];
            $port = $port ? $port : Connection::CLIENT_PORT;

            /**
             *
             * prepare url
             */
            $url = ($server->secure ? 'https://' : 'http://') . $hostname.':'.$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;
    }



}
