<?php

namespace ModulesGarden\Servers\OpenXchange\App\UI\Client\EmailAccount\Providers;

use ModulesGarden\Servers\OpenXchange\App\Libs\RestApi;
use ModulesGarden\Servers\OpenXchange\App\Helpers\Helper;
use ModulesGarden\Servers\OpenXchange\App\UI\Client\EmailAccount\Constants;
use ModulesGarden\Servers\OpenXchange\App\UI\Client\EmailAlias\Providers\AddEmailAliasDataProvider;
use ModulesGarden\Servers\OpenXchange\Core\UI\ResponseTemplates\HtmlDataJsonResponse;
use ModulesGarden\Servers\OpenXchange\Core\UI\Widget\Forms\DataProviders\BaseDataProvider;
use ModulesGarden\OpenXchangeAddon\Core\Models\ModuleSettings\Model;
use ModulesGarden\Servers\OpenXchange\App\Models\ProductConfiguration;
use ModulesGarden\Servers\OpenXchange\Core\Models\Whmcs\ProductConfigOption;

/**
 *
 * Created by PhpStorm.
 * User: Tomasz Bielecki ( tomasz.bi@modulesgarden.com )
 * Date: 10.09.19
 * Time: 13:06
 * Class AccountDataProvider
 */
class AccountDataProvider extends BaseDataProvider
{
    public function read()
    {
        $hid                  = $this->request->getValue('id');
        $hosting              = \WHMCS\Service\Service::find($hid);
        $this->data['domain'] = $hosting->domain;

        //set default values for lang and timezone
        $defLang = Model::where('setting', '=', 'languagedef')->get()->toArray();

        if (is_array($defLang) && !empty($defLang) && $defLang[0]['value'] && $defLang[0]['value'] != '')
        {
            $this->data['language'] = $defLang[0]['value'];
        }

        $defTimezone = Model::where('setting', '=', 'timezone')->get()->toArray();

        if (is_array($defTimezone) && !empty($defTimezone) && $defTimezone[0]['value'] && $defTimezone[0]['value'] != '')
        {
            $this->data['timezone'] = $defTimezone[0]['value'];
        }

        //get timezone and language data from session
        if (\WHMCS\Session::get('OXModule_last_timezone') != '')
        {
            $this->data['timezone'] = \WHMCS\Session::get('OXModule_last_timezone');
        }

        if (\WHMCS\Session::get('OXModule_last_language') != '')
        {
            $this->data['language'] = \WHMCS\Session::get('OXModule_last_language');
        }

        //get avaliable lang
        $langDataRaw = Model::where('setting', '=', 'language')->get()->toArray();
        $langData    = unserialize($langDataRaw[0]['value']);

        if (is_array($langData) && !empty($langData))
        {
            foreach (Constants::LANGUAGES as $name => $language)
            {
                if (in_array($language, $langData))
                {
                    $this->availableValues['language'][$language] = $name;
                }
            }
        }
        else
        {
            foreach(Constants::LANGUAGES as $name => $language)
            {
                $this->availableValues['language'][$language] = $name;
            }
        }

        $this->optGroups['timezone'] = Constants::TIMEZONES;
        
        //check if autofill option is "on" autofillGen
        $autofillOptRaw = Model::where('setting', '=', 'autofill')->get()->toArray();
        
        $this->data['autofillGen'] = $autofillOptRaw[0]['value'];
        
        //check if this is freemium model product
        $params  = Helper::moduleParams($this->request->getValue('id'));
        $freeAcc = Helper::freeAccountsLimit($params);
        
        $this->availableValues['emailType']      = $this->getAvailableEmailTypes($params);
        $this->availableValues['emailAddonType'] = $this->getAvailableAddons($params);

        
        //if ($freeAcc > 0)
        //{
            /*$this->availableValues['emailType'] = [
                'cloud_pim'                   => 'Mail Essential',
                'cloud_productivity'          => "Add-on Productivity",
                'cloud_security'              => "Add-on Security",
                'cloud_productivity_security' => "Add-on Productivity-Security",
            ];*/
        //}
    }
    
    public function getAvailableAddons($params)
    {
        $configOptions     = $params['configoptions'];
        $allowedAddonsData = [];
        
        if ($configOptions && !empty($configOptions))
        {
            if (isset($configOptions['acc_limit_guard']) && $configOptions['acc_limit_guard'] > 0)
            {
                $allowedAddonsData['guard'] = array_search('guard', Constants::getTranslatedAddons());
            }
            
            if (isset($configOptions['acc_limit_ai']) && $configOptions['acc_limit_ai'] > 0)
            {
                $allowedAddonsData['ai'] = array_search('ai', Constants::getTranslatedAddons());
            }
        }

        if (empty($allowedAddonsData))
        {
            $config = ProductConfiguration::config($params['packageid']);

            if ($config['email_accounts_guard'] && $config['email_accounts_guard'] != 0)
            {
                $allowedAddonsData['guard'] = array_search('guard', Constants::getTranslatedAddons());
            }

            if ($config['email_accounts_ai'] && $config['email_accounts_ai'] != 0)
            {
                $allowedAddonsData['ai'] = array_search('ai', Constants::getTranslatedAddons());
            }
        }

        return $allowedAddonsData;
    }
    
    public function getAvailableEmailTypes($params) 
    {
        $configOptions    = $params['configoptions'];
        $allowedTypesData = [];
            
        if ($configOptions && !empty($configOptions))
        {
            if (isset($configOptions['acc_limit']) && $configOptions['acc_limit'] > 0)
            {
                $config                                        = ProductConfiguration::config($params['packageid']);
                $allowedTypesData[$config['selected_product']] = array_search($config['selected_product'], Constants::getTranslatedPackages());
            }

            if (isset($configOptions['acc_limit_productivity']) && $configOptions['acc_limit_productivity'] > 0)
            {
                $allowedTypesData['cloud_productivity'] = array_search('cloud_productivity', Constants::getTranslatedAddons());
            }

            if (isset($configOptions['acc_limit_secure']) && $configOptions['acc_limit_secure'] > 0)
            {
                $allowedTypesData['cloud_security'] = array_search('cloud_security', Constants::getTranslatedAddons());
            }

            if (isset($configOptions['acc_limit_productivity_secure']) && $configOptions['acc_limit_productivity_secure'] > 0)
            {
                $allowedTypesData['cloud_productivity_security'] = array_search('cloud_productivity_security', Constants::getTranslatedAddons());
            }
        }

        //if (empty($allowedTypesData))
        //{
            $config = ProductConfiguration::config($params['packageid']);

            if ($config['product_accounts'] && $config['product_accounts'] != 0)
            {
                if (isset($configOptions['acc_limit']) && $configOptions['acc_limit'] == 0)
                {
                    //do nothing
                }
                else
                {
                    $allowedTypesData[$config['selected_product']] = array_search($config['selected_product'], Constants::getTranslatedPackages());
                }
            }
 
            if ($config['email_accounts_productivity'] && $config['email_accounts_productivity'] != 0)
            {
                if (isset($configOptions['acc_limit_productivity']) && $configOptions['acc_limit_productivity'] == 0)
                {
                    //do nothing
                }
                else
                {
                    $allowedTypesData['cloud_productivity'] = array_search('cloud_productivity', Constants::getTranslatedAddons());
                }
            }

            if ($config['email_accounts_security'] && $config['email_accounts_security'] != 0)
            {
                if (isset($configOptions['acc_limit_secure']) && $configOptions['acc_limit_secure'] == 0)
                {
                    //do nothing
                }
                else
                {
                    $allowedTypesData['cloud_security'] = array_search('cloud_security', Constants::getTranslatedAddons());
                }
            }

            if ($config['email_accounts_productivity_security'] && $config['email_accounts_productivity_security'] != 0)
            {
                if (isset($configOptions['acc_limit_productivity_secure']) && $configOptions['acc_limit_productivity_secure'] == 0)
                {
                    //do nothing
                }
                else
                {
                    $allowedTypesData['cloud_productivity_security'] = array_search('cloud_productivity_security', Constants::getTranslatedAddons());
                }
            }
        //}

        return $allowedTypesData;
    }

    public function create()
    {
        try
        {
            $params           = Helper::moduleParams($this->request->getValue('id'));
            $limit            = Helper::accountsLimit($params);
            $limit2           = Helper::quotaLimit($params);
            $maxQuota         = Helper::maxQuotaLimit($params);
            $accountsAndQuota = $this->countUsersAndQuota($params);
            $countUsers       = $accountsAndQuota['accountsCount'];
            $quotaForContext  = $accountsAndQuota['quotaForAccounts'] + $this->formData['quota'];

            //$provider = new AddEmailAliasDataProvider();
            //$aliases  = $provider->countAliases($params);

            //check if freemium model, if yes check three email types
            $freeAcc = Helper::freeAccountsLimit($params);

            /*if($aliases >= (Helper::aliasesLimit($params) + $freeAcc))
            {
                return (new HtmlDataJsonResponse())->setMessageAndTranslate('tooManyAliases')->setStatusError();
            }*/

            //if ($freeAcc > 0)
            //{
                if ($limit == 'unlimited')
                {
                    $accLimit = 'unlimited';
                }
                else
                {
                    $accLimit        = $limit + $freeAcc;
                }
                //$accLimit        = $limit + $freeAcc;
                $accProdLimit    = Helper::accountsProdLimit($params);
                $accSecLimit     = Helper::accountsSecLimit($params);
                $accProdSecLimit = Helper::accountsProdSecLimit($params);
                $accGuardLimit   = Helper::accountsGuardLimit($params);
                $accAiLimit      = Helper::accountsAiLimit($params);
                $selectedType    = $this->formData['emailType'];

                switch ($selectedType)
                {
                    case 'cloud_pim':
                        if ($accLimit != 'unlimited' && $accountsAndQuota['accountsCount']['emailAccs'] >= $accLimit)
                        {
                            return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountsLimitEss')->setStatusError();
                        }

                        break;
                    case 'cloud_single_web':
                        if ($accLimit != 'unlimited' && $accountsAndQuota['accountsCount']['emailAccs'] >= $accLimit)
                        {
                            return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountsLimitBasic')->setStatusError();
                        }

                        break;
                    case 'cloud_productivity_guard':
                        if ($accLimit != 'unlimited' && $accountsAndQuota['accountsCount']['emailAccs'] >= $accLimit)
                        {
                            return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountsLimitPremium')->setStatusError();
                        }

                        break;
                    case 'cloud_productivity':
                        if($accProdLimit != 'unlimited' && $accountsAndQuota['accountsCount']['emailProdAccs'] >= $accProdLimit)
                        {
                            return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountsLimitProd')->setStatusError();
                        }

                        break;
                    case 'cloud_security':
                        if($accSecLimit != 'unlimited' && $accountsAndQuota['accountsCount']['emailSecAccs'] >= $accSecLimit)
                        {
                            return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountsLimitSec')->setStatusError();
                        }

                        break;
                    case 'cloud_productivity_security':
                        if($accProdSecLimit != 'unlimited' && $accountsAndQuota['accountsCount']['emailProdSecAccs'] >= $accProdSecLimit)
                        {
                            return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountsLimitProdSec')->setStatusError();
                        }

                        break;
                    default:
                        break;
                }
            /*}
            else
            {
                if($countUsers >= $limit)
                {
                    return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountsLimit')->setStatusError();
                }
            }*/

            $selectedAddons = $this->formData['emailAddonType'];

            if ($selectedAddons && !empty($selectedAddons))
            {
                foreach ($selectedAddons as $selectedAddon)
                {
                    if ($selectedAddon == 'guard')
                    {
                        if($accGuardLimit != 'unlimited' && $accountsAndQuota['accountsCount']['emailGuardAccs'] >= $accGuardLimit)
                        {
                            return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountsLimitGuard')->setStatusError();
                        }
                    }
                    elseif($selectedAddon == 'ai')
                    {
                        if($accAiLimit != 'unlimited' && $accountsAndQuota['accountsCount']['emailAiAccs'] >= $accAiLimit)
                        {
                            return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountsLimitAi')->setStatusError();
                        }
                    }
                }
            }

            if($this->formData['quota'] <= 0)
            {
                return (new HtmlDataJsonResponse())->setMessageAndTranslate('quotaLimitWrong')->setStatusError();
            }

            if($limit2 > 0 && $this->formData['quota'] > $limit2)
            {
                return (new HtmlDataJsonResponse())->setMessageAndTranslate('quotaLimit')->setStatusError();
            }

            if($quotaForContext > $maxQuota)
            {
                return (new HtmlDataJsonResponse())->setMessageAndTranslate('quotaLimitExtended')->setStatusError();
            }

            $domainPunnycode = \WHMCS\Domains\Idna::toPunycode($this->formData['domain']);

            $parameters = [
                //'display_name' => $this->formData['display_name'],
                'display_name' => $this->formData['firstname'].' '.$this->formData['lastname'],
                'given_name'   => $this->formData['firstname'],
                'sur_name'     => $this->formData['lastname'],
                'language'     => $this->formData['language'],
                'timezone'     => $this->formData['timezone'],
                'quota'        => $this->formData['quota'],
                'name'         => $this->formData['username'].'@'.$domainPunnycode,
                'primaryEmail' => $this->formData['username'].'@'.$domainPunnycode,
                'password'     => $this->formData['password']
            ];
            
            if (isset($this->formData['emailType']) && $this->formData['emailType'] != '')
            {
                if ($this->formData['emailType'] == 'cloud_productivity_guard')
                {
                    $parameters['emailType'] = ['cloud_productivity', 'guard'];
                }
                else
                {
                    $parameters['emailType'] = [$this->formData['emailType']];
                }
            }
            else
            {
                $config                  = ProductConfiguration::config($params['packageid']);
                $parameters['emailType'] = [$config['selected_product']];
            }

            if ($selectedAddons && !empty($selectedAddons))
            {
                if (in_array('guard', $selectedAddons))
                {
                    if (!in_array('guard', $parameters['emailType']))
                    {
                        array_push($parameters['emailType'], 'guard');
                    }
                }
                if(in_array('ai', $selectedAddons))
                {
                    array_push($parameters['emailType'], 'ai');
                }
            }

            //change pass permission
            if (isset($params['configoptions']['allow_to_change_password']) && ($params['configoptions']['allow_to_change_password'] == 1 || $params['configoptions']['allow_to_change_password'] == 'on'))
            {
                $parameters['editPasswordPerm'] = true;
            }
            else
            {
                $config = ProductConfiguration::config($params['packageid']);

                if (isset($config['allow_to_change_password']) && ($config['allow_to_change_password'] == 1 || $config['allow_to_change_password'] == 'on'))
                {
                    $parameters['editPasswordPerm'] = true;
                }
                else
                {
                    $parameters['editPasswordPerm'] = false;
                }
            }

            $context = new RestApi($params);
            $result  = $context->createUser($parameters);

            if(!empty($result->name))
            {
                //save language and timezone in session to set it nex time
                \WHMCS\Session::set('OXModule_last_timezone', $this->formData['timezone']);
                \WHMCS\Session::set('OXModule_last_language', $this->formData['language']);

                return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountHasBeenCreated')->setStatusSuccess();
            }
            else
            {
                return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountErrorCreated')->setStatusError();
            }
        }
        catch(\Exception $e)
        {
            return (new HtmlDataJsonResponse())->setMessageAndTranslate('emailAccountErrorCreated')->setStatusError();
        }
    }

    public function update()
    {
    
    }

    public function delete()
    {
    
    }

    private function countUsersAndQuota($params)
    {
        $context         = new RestApi($params);
        $usersList       = $context->listAllUsers();
        $config          = ProductConfiguration::config($params['packageid']);
        $selectedProduct = $config['selected_product'];

        $quotaForAccounts = 0;

        foreach($usersList as $key => $user)
        {
            if($user->isContextAdmin == true)
            {
                unset($usersList[$key]);
                continue;
            }
            
            //updateUserUnifiedQuota
            if (!property_exists($user, 'unifiedQuota'))
            {
                $context->updateUserUnifiedQuota($user->name, ['unifiedQuota' => $user->mailQuota]);
            }
            
            $quotaForAccounts += property_exists($user, 'unifiedQuota') ? $user->unifiedQuota : $user->mailQuota;
        }

        $freeAcc = Helper::freeAccountsLimit($params);

        /*if ($freeAcc > 0)
        {*/
            $emailAccs        = 0;
            //$emailAccsBasic   = 0;
            $emailProdAccs    = 0;
            $emailSecAccs     = 0;
            $emailProdSecAccs = 0;
            $emailProdGuard   = 0;
            $emailProdAi      = 0;

            foreach ($usersList as $account)
            {
                $accAttributes = $account->classOfService;

                if ((in_array('cloud_pim', $accAttributes) || in_array('cloud_single_web', $accAttributes)) && count($accAttributes) == 1)
                {
                    $emailAccs++;
                }
                elseif ((in_array('cloud_productivity', $accAttributes) && in_array('guard', $accAttributes)) && count($accAttributes) == 2)
                {
                    if ($selectedProduct == 'cloud_productivity_guard' && $config['product_accounts'] && $config['product_accounts'] > 0)
                    {
                        $emailAccs++;
                    }
                    else
                    {
                        $emailProdAccs++;
                        $emailProdGuard++;
                    }
                }
                elseif ((in_array('cloud_productivity', $accAttributes) && in_array('guard', $accAttributes)) && in_array('ai', $accAttributes))
                {
                    if ($selectedProduct == 'cloud_productivity_guard' && $config['product_accounts'] && $config['product_accounts'] > 0)
                    {
                        $emailAccs++;
                        $emailProdAi++;
                    }
                    else
                    {
                        $emailProdAccs++;
                        $emailProdGuard++;
                        $emailProdAi++;
                    }
                }
                else
                {
                    if (in_array('cloud_pim', $accAttributes))
                    {
                        $emailAccs++;
                    }
                    if (in_array('cloud_single_web', $accAttributes))
                    {
                        $emailAccs++;
                    }
                    if (in_array('cloud_productivity', $accAttributes))
                    {
                        $emailProdAccs++;
                    }
                    if(in_array('cloud_security', $accAttributes))
                    {
                        $emailSecAccs++;
                    }
                    if (in_array('cloud_productivity_security', $accAttributes))
                    {
                        $emailProdSecAccs++;
                    }
                    if (in_array('guard', $accAttributes))
                    {
                        $emailProdGuard++;
                    }
                    if (in_array('ai', $accAttributes))
                    {
                        $emailProdAi++;
                    }
                }
            }

            return ['accountsCount' => [
                'emailAccs'        => $emailAccs,
                'emailProdAccs'    => $emailProdAccs,
                'emailProdSecAccs' => $emailProdSecAccs,
                'emailSecAccs'     => $emailSecAccs,
                'emailGuardAccs'   => $emailProdGuard,
                'emailAiAccs'      => $emailProdAi],
                'quotaForAccounts' => $quotaForAccounts
            ];
        /*}
        else
        {
            return ['accountsCount' => count($usersList), 'quotaForAccounts' => $quotaForAccounts];
        }*/
    }
}
