<?php

namespace ModulesGarden\Servers\OpenXchange\App\Helpers;

use ModulesGarden\Servers\OpenXchange\App\Models\ProductConfiguration;
use ModulesGarden\Servers\OpenXchange\Core\Models\Whmcs\Upgrade;
use ModulesGarden\Servers\OpenXchange\Core\Models\Whmcs\Servers;
use ModulesGarden\Servers\OpenXchange\App\Libs\RestApi;
use function \ModulesGarden\Servers\OpenXchange\Core\Helper\di;

class Helper
{
    public static function moduleParams($hid)
    {
        if(!function_exists("ModuleBuildParams"))
        {
            require_once ROOTDIR.'/includes/modulefunctions.php';
        }
        return ModuleBuildParams($hid);
    }

    //----------FREEMIUM MODEL START----------
    public static function freeAccountsLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);
        $limit  = $config['free_mailboxes'];

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        return $limit;
    }

    public static function accountsProdLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);

        if (isset($params['configoptions']['acc_limit_productivity']) && $params['configoptions']['acc_limit_productivity'] != '')
        {
            $limit = $params['configoptions']['acc_limit_productivity'];
        }
        else
        {
            $limit = $config['email_accounts_productivity'];
        }

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        if ($limit == '-1' || $limit == -1)
        {
            $limit = 'unlimited';
        }

        return $limit;
    }

    public static function accountsSecLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);

        if (isset($params['configoptions']['acc_limit_secure']) && $params['configoptions']['acc_limit_secure'] != '')
        {
            $limit = $params['configoptions']['acc_limit_secure'];
        }
        else
        {
            $limit = $config['email_accounts_security'];
        }

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        if ($limit == '-1' || $limit == -1)
        {
            $limit = 'unlimited';
        }

        return $limit;
    }
    //----------FREEMIUM MODEL STOP----------

    public static function accountsProdSecLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);

        if (isset($params['configoptions']['acc_limit_productivity_secure']) && $params['configoptions']['acc_limit_productivity_secure'] != '')
        {
            $limit = $params['configoptions']['acc_limit_productivity_secure'];
        }
        else
        {
            $limit = $config['email_accounts_productivity_security'];
        }

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        if ($limit == '-1' || $limit == -1)
        {
            $limit = 'unlimited';
        }

        return $limit;
    }
    
    public static function accountsGuardLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);

        if (isset($params['configoptions']['acc_limit_guard']) && $params['configoptions']['acc_limit_guard'] != '')
        {
            $limit = $params['configoptions']['acc_limit_guard'];
        }
        else
        {
            $limit = $config['email_accounts_guard'];
        }

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        if ($limit == '-1' || $limit == -1)
        {
            $limit = 'unlimited';
        }

        return $limit;
    }
    
    public static function accountsAiLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);

        if (isset($params['configoptions']['acc_limit_ai']) && $params['configoptions']['acc_limit_ai'] != '')
        {
            $limit = $params['configoptions']['acc_limit_ai'];
        }
        else
        {
            $limit = $config['email_accounts_ai'];
        }

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        if ($limit == '-1' || $limit == -1)
        {
            $limit = 'unlimited';
        }

        return $limit;
    }

    public static function accountsLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);

        if (isset($params['configoptions']['acc_limit']) && $params['configoptions']['acc_limit'] != '')
        {
            $limit = $params['configoptions']['acc_limit'];
        }
        else
        {
            $limit = $config['product_accounts'];
        }

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        if ($limit == '-1' || $limit == -1)
        {
            $limit = 'unlimited';
        }

        return $limit;
    }

    public static function aliasesLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);

        if (isset($params['configoptions']['alias_limit']) && $params['configoptions']['alias_limit'] != '')
        {
            $limit = $params['configoptions']['alias_limit'];
        }
        else
        {
            $limit = $config['alias_limit'];
        }

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        return $limit;
    }

    public static function forwardingAliasesLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);

        if (isset($params['configoptions']['forwarding_alias_limit']) && $params['configoptions']['forwarding_alias_limit'] != '')
        {
            $limit = $params['configoptions']['forwarding_alias_limit'];
        }
        else
        {
            $limit = $config['forwarding_alias_limit'];
        }

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        return $limit;
    }

    public static function quotaLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);

        if (isset($params['configoptions']['user_quota']) && $params['configoptions']['user_quota'] != '')
        {
            $limit = $params['configoptions']['user_quota'];
        }
        else
        {
            $limit = $config['user_quota'];
        }

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        return $limit;
    }

    public static function maxQuotaLimit($params)
    {
        $config = ProductConfiguration::config($params['packageid']);
        //$limit  = $config['quota'];
        
        if (isset($params['configoptions']['max_quota']) && $params['configoptions']['max_quota'] != '')
        {
            $limit = $params['configoptions']['max_quota'];
        }
        else
        {
            $limit = $config['quota'];
        }

        if (!$limit || $limit == '')
        {
            $limit = 0;
        }

        return $limit;
    }
    
    public static function getCoSForUpdate($params, $config)
    {
        $classOfService = [];

        //check the congifurable options first
        if (!empty($params['configoptions']))
        {
            if (isset($params['configoptions']['acc_limit']) && $params['configoptions']['acc_limit'] !== 0)
            {
                $classOfService[] = 'cloud_pim';
            }

            if (isset($params['configoptions']['acc_limit_productivity']) && $params['configoptions']['acc_limit_productivity'] !== 0)
            {
                $classOfService[] = 'cloud_productivity';
            }

            if (isset($params['configoptions']['acc_limit_secure']) && $params['configoptions']['acc_limit_secure'] !== 0)
            {
                $classOfService[] = 'cloud_security';
            }

            if (isset($params['configoptions']['acc_limit_productivity_secure']) && $params['configoptions']['acc_limit_productivity_secure'] !== 0)
            {
                $classOfService[] = 'cloud_productivity_security';
            }
        }
        
        if (empty($classOfService))
        {
            if ($config['email_accounts'] && $config['email_accounts'] != 0)
            {
                $classOfService[] = 'cloud_pim';
            }
 
            if ($config['email_accounts_productivity'] && $config['email_accounts_productivity'] != 0)
            {
                $classOfService[] = 'cloud_productivity';
            }

            if ($config['email_accounts_security'] && $config['email_accounts_security'] != 0)
            {
                $classOfService[] = 'cloud_security';
            }

            if ($config['email_accounts_productivity_security'] && $config['email_accounts_productivity_security'] != 0)
            {
                $classOfService[] = 'cloud_productivity_security';
            }
        }

        return $classOfService;
    }
    
    public static function getCurrentCOS($params)
    {
        $serviceId   = $params['serviceid'];
        $upgradeData = Upgrade::where('relid', '=', $serviceId)->where('type', '=', 'package')->where('status', '=', 'Pending')->first();

        if ($upgradeData && !empty($upgradeData))
        {
            $oldPackage = $upgradeData->originalvalue;
            $config     = ProductConfiguration::config($oldPackage);
            $oldCos     = self::getCoSForUpdate($params, $config);

            return $oldCos;
        }
        else
        {
            return false;
        }
    }
    
    public static function checkIfAccountTypeChanged($currentAccountData, $selectedEmailType)
    {
        $currentClassOfService = $currentAccountData->classOfService;

        if ($selectedEmailType == 'cloud_productivity_guard')
        {
            if (in_array('cloud_productivity', $currentClassOfService) && in_array('guard', $currentClassOfService) && count($currentClassOfService) == 2)
            {
                //class of service was not changed
                return false;
            }
            else
            {
                return true;
            }
        }
        else
        {
            if (in_array($selectedEmailType, $currentClassOfService))
            {
                //class of service was not changed
                return false;
            }
            else
            {
                return true;
            }
        }
    }

    public static function convertEmailFromPunnycode($email)
    {
        $emailTmp      = explode('@', $email);
        $domainUnicode = \WHMCS\Domains\Idna::fromPunycode($emailTmp[1]);
        $emailTmp[1]   = $domainUnicode;

        return implode('@', $emailTmp);
    }

    public static function convertEmailToPunnycode($email)
    {
        $emailTmp      = explode('@', $email);
        $domainUnicode = \WHMCS\Domains\Idna::toPunycode($emailTmp[1]);
        $emailTmp[1]   = $domainUnicode;

        return implode('@', $emailTmp);
    }

    public static function checkIfDomainAlreadyExistsOnWhmcsOrOpenXchange()
    {
        $errors   = [];
        $lang     = di('lang');

        foreach($_SESSION['cart']['products'] as $product)
        {
            $productModel = \WHMCS\Product\Product::find($product['pid']);

            if($productModel->servertype != 'OpenXchange'){
                continue;
            }
            $config = ProductConfiguration::config($product['pid']);

            if($config['own_domains'] == "on"){
                $domain = \WHMCS\Domain\Domain::where('domain', $product['domain'])
                    ->whereIn('status', ['Active', 'Pending', 'Pending Transfer', 'Pending Registration'])
                    ->first();
                if(empty($domain->id)){
                    foreach($_SESSION['cart']['domains'] as $domainInCart)
                    {
                        if ($domainInCart['domain'] == $product['domain']) {
                            continue 2;
                        }
                    }
                    $errors[] = $lang->T('ownDomainNeed').$productModel->name.' ('.$product['domain'].')';
                }
            }

            // check if domain already exists on OpenXchange servers
            $oxErrors = self::checkOXServers($product['domain']);
            if(!empty($oxErrors)){
                // scalamy tablice płasko
                $errors = array_merge($errors, $oxErrors);
            }
        }

        return $errors;
    }

    private static function checkOXServers($domain)
    {
        //get ALL OpenXchange servers with status active
        $allOpenXchangeServers = Servers::where('type', '=', 'OpenXchange')->where('active', '=', 1)->where('disabled', '=', 0)->get();
        $errors                = [];
        $lang                  = di('lang');

        //check context with provided domain already exists
        if ($allOpenXchangeServers && !empty($allOpenXchangeServers))
        {
            foreach ($allOpenXchangeServers as $oxServer)
            {
                $params = [
                    'serversecure'   => $oxServer->secure == 'on' ? 'https://' : 'http://',
                    'serverhostname' => $oxServer->hostname,
                    'serverusername' => $oxServer->username,
                    'serverpassword' => decrypt($oxServer->password)
                ];

                $api         = new RestApi($params);
                $contextName = $oxServer->username . "_" . str_replace('=', '', base64_encode(\WHMCS\Domains\Idna::toPunycode($domain)));
                $contexts    = $api->listContexts();

                foreach ($contexts as $context)
                {
                    if ($context->name == $contextName)
                    {
                        $errors[] = sprintf($lang->T('contextAlreadyExists'), $domain);
                        continue;
                    }
                }
            }
        }

        return $errors;
    }
}
