<?php

namespace ModulesGarden\Servers\ZimbraEmail\App\UI\Admin\ProductConfiguration\Providers;

use ModulesGarden\Servers\ZimbraEmail\App\Enums\ProductParams;
use ModulesGarden\Servers\ZimbraEmail\App\Enums\Size;
use ModulesGarden\Servers\ZimbraEmail\App\Enums\Zimbra;
use ModulesGarden\Servers\ZimbraEmail\App\Helpers\ZimbraManager;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Repository;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Repository\ClassOfServices;
use ModulesGarden\Servers\ZimbraEmail\App\Traits\LangHandler;
use ModulesGarden\Servers\ZimbraEmail\App\Traits\ServerParams;
use ModulesGarden\Servers\ZimbraEmail\App\Traits\ZimbraApiHandler;
use ModulesGarden\Servers\ZimbraEmail\Core\App\Controllers\Interfaces\AdminArea;
use ModulesGarden\Servers\ZimbraEmail\Core\Traits\Lang;
use ModulesGarden\Servers\ZimbraEmail\Core\UI\Widget\Forms\DataProviders\BaseDataProvider;
use \ModulesGarden\Servers\ZimbraEmail\App\Models\ProductConfiguration;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Migrations\Drivers\Version1To2;
use \Illuminate\Database\Capsule\Manager as DB;

/**
 *
 * Created by PhpStorm.
 * User: Tomasz Bielecki ( tomasz.bi@modulesgarden.com )
 * Date: 29.08.19
 * Time: 10:27
 * Class ProductConfigurationDataProvider
 */
class ProductConfigurationDataProvider extends BaseDataProvider implements AdminArea
{

    const FORM_DATA = [
            'acc_limit',
            'acc_base',
            'alias_limit',
            'cos_name',
            'login_link',
            'filterAccountsByCOS',
            'acc_size',
            'domain_alias_limit',
            'dist_list_limit',
            'domainMaxSize',
            'domainBaseSize',
            'cos',
            'ca_emailAccountPage',
            'ca_distributionListPage',
            'ca_goToWebmailPage',
            'ca_emailAliasesPage',
            'ca_domainAliasesPage',
            'ca_logInToMailboxButton',
        ];

    const FILED_NOT_UPDATED = [
        'login_link'
    ];

    use LangHandler;

    /**
     *
     */
    public function read()
    {
        /**
         * load params from previous version
         */
        $this->checkConfigOrLoadFromPrevious($this->getRequestValue('id'));

        $this->loadDefaultData();
        $this->overrideDefaultDataByProductConfig();
    }

    /**
     *
     */
    public function update()
    {
        $this->catchFormData();

        $cos = $this->formData['cos'];
        unset($this->formData['cos']);

        $productId = $this->request->get('id');

        foreach ($this->formData as $key => $value)
        {
            ProductConfiguration::updateOrCreate(['product_id' => $productId, 'setting' => $key], ['value' => $value]);
        }

        /**
         * save  serialized cos
         */
        ProductConfiguration::updateOrCreate(['product_id' => $productId, 'setting' => 'cos'], ['value' => json_encode($cos)]);
    }

    /**
     *
     */
    protected function loadDefaultData()
    {
        /* default data */
        $this->data['acc_limit']          = Size::DEFAULT_ACC_LIMIT;
        $this->data['acc_base']           = Size::DEFAULT_ACC_BASE;
        $this->data['acc_size']           = Size::DEFAULT_ACC_SIZE;
        $this->data['alias_limit']        = Size::DEFAULT_ALIAS_LIMIT;
        $this->data['domain_alias_limit'] = Size::DEFAULT_DOMAIN_ALIAS_LIMIT;
        $this->data['cos_name']           = ClassOfServices::CUSTOM_ZIMBRA;
        $this->data['dist_list_limit']    = Size::DEFAULT_DIST_ALIAS_LIMIT;
        $this->data['login_link']         = Zimbra::DEFAULT_LOGIN_LINK;
        $this->data['domainMaxSize']      = Size::UNLIMITED;
        $this->data['domainBaseSize']     = Size::UNLIMITED;

        /* available class of services*/
        $this->availableValues['cos_name'] = [
            ClassOfServices::CUSTOM_ZIMBRA          => $this->getLang()->absoluteT('addonAA', 'configuration', 'product', 'zimbra', 'cos', 'Use Custom Settings'),
            ClassOfServices::ZIMBRA_CONFIG_OPTIONS  => $this->getLang()->absoluteT('addonAA', 'configuration', 'product', 'zimbra', 'cos', 'Allow clients to choose Class Of Service'),
            ClassOfServices::CLASS_OF_SERVICE_QUOTA => $this->getLang()->absoluteT('addonAA', 'configuration', 'product', 'zimbra', 'cos', 'Allow clients to choose Class Of Service Quota Per Account'),
        ];


        $manager    = new ZimbraManager();
        $repository = $manager->getApiByProduct($this->getRequestValue('id'))->soap->repository();
        $cosList        = $repository->cos->all();

        /**
         * class of services from API
         */
        foreach ($cosList as $cos)
        {
            /**
             * @var $cos \ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Models\ClassOfService
             */
            $this->availableValues['cos_name'][$cos->getId()] = $this->getLang()->absoluteT($cos->getName());
        }
    }

    /**
     * @description load data from database
     */
    protected function overrideDefaultDataByProductConfig()
    {
        $settings = ProductConfiguration::where('product_id', $this->request->get('id'))->get();

        foreach ($settings as $setting)
        {
            if('cos' === $setting->setting)
            {
                $this->data[$setting->setting] = json_decode($setting->value, true);
                continue;
            }
            $this->data[$setting->setting] = $setting->value;
        }
    }

    /**
     * @description catch params from request
     */
    protected function catchFormData()
    {
        /**
         * catch from request
         */
        $params = array_merge(Zimbra::BASE_ACCOUNT_CONFIG,self::FORM_DATA);

        foreach ($params as $name)
        {
            if ($value = $this->request->get($name))
            {
                $this->formData[$name] = $value;
            }elseif(!in_array($name,self::FILED_NOT_UPDATED)){
                $this->formData[$name] = ProductParams::SWITCHER_DISABLED;
            }else{
                $this->formData[$name] = '';
            }
        }
    }


    private function checkConfigOrLoadFromPrevious($id)
    {

        if(ProductConfiguration::where('product_id', $id)->first())
        {
            return;
        }
        $migration = new Version1To2\Settings();

        $exists = DB::schema()->hasTable($migration->getFromTable());
        if(!$exists)
        {
            return;
        }

        $previous = DB::table($migration->getFromTable())->where('product_id', $id)->get();

        /**
         *
         */
        $prodManager = new ProductConfiguration();

        /**
         *
         * storage all params per product id
         */
        foreach($previous as $setting)
        {
            $settings[$setting->product_id][$setting->setting] = $setting->value;
            $products[] = $setting->product_id;
        }

        /**
         *
         * update setting data & save
         */
        foreach($settings as $prodId => $settingsArray)
        {
            $attrs = $migration->updateValues($settingsArray, $prodId);

            foreach($attrs as $key => $value)
            {
                $prodManager->updateOrCreate(['product_id' => $prodId, 'setting' => $key],['value' => $value]);
            }
        }

        /**
         *
         * new options
         */
        foreach($migration->getNewFields() as $key => $value)
        {

            $prodManager->updateOrCreate(['product_id' => $id, 'setting' => $key],['value' => $value]);
        }

    }
}