<?php
/**
 * Class CreateAccount
 * User: Nessandro
 * Date: 2019-10-07
 * Time: 10:41
 * @package ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Services\Create
 */

namespace ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Services\Create;


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\Libs\Product\ProductManager;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Interfaces\ApiService;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Models\Account;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Traits\ProductManagerHandler;
use ModulesGarden\Servers\ZimbraEmail\Core\Helper\ConfigOptionsHelper;

class CreateAccount extends ApiService
{
    use ProductManagerHandler;
    use \ModulesGarden\Servers\ZimbraEmail\Core\UI\Traits\RequestObjectHandler;

    /**
     * added more conditions
     * @return bool
     */
    protected function isValid()
    {
        /**
         * check if product manager is set
         */
        if(!$this->productManager)
        {
            $this->setError('Product Manager Not Found');
            return false;
        }

        /**
         * domain name
         */
        if(!$this->formData['domain'])
        {
            $this->setError('Domain name can not be found.');
            return false;
        }

        /**
         * check full usages of domains
         */
        $maxDomainQuota = $this->productManager->get('domainMaxSize') * Size::B_TO_GB;
        $usages = $this->api->repository()->accounts->getFullUsages($this->formData['domain']);

        if($maxDomainQuota !== Size::UNLIMITED && $usages >= $maxDomainQuota)
        {
            $this->setError("Domain size limit has been reached");
            return false;
        }

        /**
         *
         * Check if accounts limit has been reached
         */
        $hosting = $this->productManager->getHosting();
        $configOption = new ConfigOptionsHelper;
        $acc_addObj = $configOption->getConfigurableOption($hosting->id, 'acc_add');
        $acc_add = $acc_addObj->qty ? $acc_addObj->qty : 0;
        $accountLimit = $this->productManager->get('acc_base') + $acc_add;
        $mailBoxes = $this->getMailboxes();

        if(count($mailBoxes) >= $accountLimit && $accountLimit !== ProductParams::SIZE_UNLIMITED && 'editAccountForm' !== $this->getRequestValue('loadData'))
        {
            $this->setError('There are too many mailboxes');
            return false;
        }

        /**
         *
         */
        return parent::isValid();
    }

    /**
     * @return mixed
     */
    protected function getMailboxes()
    {
        $mailBoxes = $this->api->repository()->accounts->getMailboxes($this->formData['domain']);
        return $mailBoxes;
    }

    /**
     * @return Account
     */
    protected function getModel()
    {
        $accountSize = $this->productManager->get(ProductParams::ACCOUNT_SIZE);
        /**
         * create new account in zimbra
         */
        $account = new Account();
        $account->setName($this->formData['username'].'@'.$this->formData['domain']);
        $account->setPassword(html_entity_decode($this->formData['password']), ENT_QUOTES);
        /**
         *  set account attributes
         */
        $account->setAttr(Account::ATTR_FIRSTNAME, $this->formData['firstname']);
        $account->setAttr(Account::ATTR_LASTNAME, $this->formData['lastname']);
        $account->setAttr(Account::ATTR_PHONE, $this->formData['phone']);
        $account->setAttr(Account::ATTR_MOBILE_PHONE, $this->formData['mobile_phone']);
        $account->setAttr(Account::ATTR_FAX, $this->formData['fax']);
        $account->setAttr(Account::ATTR_PAGER, $this->formData['pager']);
        $account->setAttr(Account::ATTR_HOME_PHONE, $this->formData['home_phone']);
        $account->setAttr(Account::ATTR_COUNTRY, $this->formData['country']);
        $account->setAttr(Account::ATTR_STATE, $this->formData['state']);
        $account->setAttr(Account::ATTR_PROF_TITLE, $this->formData['title']);
        $account->setAttr(Account::ATTR_POSTAL_CODE, $this->formData['post_code']);
        $account->setAttr(Account::ATTR_CITY, $this->formData['city']);
        $account->setAttr(Account::ATTR_STREET, $this->formData['street']);
        $account->setAttr(Account::ATTR_COMPANY, $this->formData['company']);
        $account->setAttr(Account::ATTR_ACCOUNT_STATUS, $this->formData['status']);
        $account->setAttr(Account::ATTR_DISPLAY_NAME, $this->formData['display_name']);
        $account->setAttr(Account::ATTR_MAIL_QUOTA, $accountSize * Size::B_TO_MB);

        foreach($this->productManager->getZimbraConfiguration() as $key => $value)
        {
            $value = $value === ProductParams::SWITCHER_ENABLED ? Zimbra::ATTR_ENABLED : Zimbra::ATTR_DISABLED;
            $account->setAttr($key, $value);
        }

        return $account;
    }

    /**
     * @return bool|mixed|Account|void
     */
    protected function process()
    {
        /**
         *
         */
        $model = $this->getModel();

        /**
         * create account in ZIMBRA
         */
        $result = $this->api->account->create($model);

        /**
         * problem with create account
         */
        if(!$result)
        {
            $this->setError($this->api->account->getError());
            return false;
        }

        return $result;
    }
}