<?php
/**
 * Class DistributionList
 * User: ThurData
 * Date: 2019-10-01
 * Time: 08:45
 * @package ThurData\Servers\KerioEmail\App\Libs\Kerio\Components\Api\Soap\Services\Create
 */

namespace ThurData\Servers\KerioEmail\App\Libs\Kerio\Components\Api\Soap\Services\Create;


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\Interfaces\ApiService;
use \ThurData\Servers\KerioEmail\App\Libs\Kerio\Components\Api\Soap\Models\DistributionList;
use ThurData\Servers\KerioEmail\App\Libs\Kerio\Components\Api\Soap\Models\Domain;
use ThurData\Servers\KerioEmail\App\Libs\Kerio\Components\Api\Soap\Traits\ProductManagerHandler;
use ThurData\Servers\KerioEmail\Core\Http\Request;

class CreateDistributionList extends ApiService
{
    use ProductManagerHandler;

    public function isValid()
    {
        /**
         *
         * check that the owners are valid
         */
        foreach($this->formData['owners'] as $owner)
        {
            $result = $this->api->account->getAccountId($owner);
            if($result->getLastError())
            {
                $this->setError($result->getLastError());
                return false;
            }
        }

        /**
         *
         * check that the domains from aliases are valid
         */
        foreach($this->formData['emailAliases'] as $alias)
        {
            $aliasParts = explode('@', $alias);
            $domain = new Domain();
            $domain->setName($aliasParts[1]);
            $result = $this->api->domain->getDomain($domain);
            if($result->getLastError())
            {
                $this->setError($result->getLastError());
                return false;
            }
        }

        $listLimit = $this->productManager->get('dist_list_limit');
        $usages = $this->api->repository()->lists->getAllDistributionListsByDomain($this->formData['domain']);
        if(is_countable($usages)){
            if($listLimit !== Size::UNLIMITED && count($usages) >= $listLimit)
            {
                $this->setError("Distribution list limit has been reached");
                return false;
            }
        }
        return parent::isValid();
    }

    protected function process()
    {
        $list = $this->getModel();

        /**
         * create list
         */
        $distList = $this->api->distributionList->create($list);

        if(!$distList)
        {
            $this->setError($this->api->distributionList->getLastResult()->getLastErrorCode());
            return false;
        }

        /**
         *
         * add members to distribution list
         */
        $this->addListMembers($distList, $this->formData['memberList']);

        /**
         *
         * add owners to distribution list
         */
        $this->addListOwners($distList, $this->formData['owners']);

        /**
         *
         * add aliases to list
         */
        $this->addListAliases($distList, $this->formData['emailAliases']);

        return true;
    }

    /**
     * @return DistributionList
     */
    protected function getModel()
    {
        $email = $this->formData['listmail'].'@'.$this->formData['domain'];
        $list = new DistributionList();
        $list->setName($email);
        $list->setAttr(DistributionList::ATTR_DISPLAY_NAME,$this->formData['displayName']);
        $list->setAttr(DistributionList::ATTR_DESCRIPTION,$this->formData['description']);
        $list->setAttr(DistributionList::ATTR_SUBSCRIPTION_REQUEST,$this->formData['subscriptionRequest']);
        $list->setAttr(DistributionList::ATTR_UNSUBSCRIPTION_REQUEST,$this->formData['unsubscriptionRequest']);
        $list->setAttr(DistributionList::REPLY_TO_DISPLAY,$this->formData['replyDisplayName']);
        $list->setAttr(DistributionList::REPLY_TO_ADDRESS,$this->formData['replyEmailAddress']);


        $notify = $this->formData['sharesNotify'] === ProductParams::SWITCHER_ENABLED ? Kerio::ATTR_ENABLED : Kerio::ATTR_DISABLED;
        $list->setAttr(DistributionList::ATTR_NOTIFY_SHARES,$notify);

        $hideGal = $this->formData['hideGal'] === ProductParams::SWITCHER_ENABLED ? Kerio::ATTR_ENABLED : Kerio::ATTR_DISABLED;
        $list->setAttr(DistributionList::ATTR_HIDE_IN_GAL,$hideGal);

        $status = $this->formData['receiveMail'] === ProductParams::SWITCHER_ENABLED ? Kerio::ENABLED : Kerio::DISABLED;
        $list->setAttr(DistributionList::ATTR_MAIL_STATUS,$status);

        $replyEnabled = $this->formData['replyEmail'] === ProductParams::SWITCHER_ENABLED ? Kerio::ATTR_ENABLED : Kerio::ATTR_DISABLED;
        $list->setAttr(DistributionList::REPLY_TO_ENABLED,$replyEnabled);


        if($this->formData['dynamicGroup'] === ProductParams::SWITCHER_ENABLED)
        {
            $list->setDynamic(true);
        }

        return $list;
    }

    /**
     *
     * add members to existing list list
     *
     * @param DistributionList $distList
     * @param array $members
     * @return bool
     */
    public function addListMembers(DistributionList $distList, $members = [])
    {
        /**
         * check if available some members
         */
        if(!$members)
        {
            return true;
        }

        /**
         * update object by members
         */
        foreach ($members as $member)
        {
            if($member)
            {
                $distList->addMember($member);
            }
        }

        /**
         *
         * add members to list
         */
        $result = $this->api->distributionList->addMembers($distList);
        if(!$result)
        {
            //todo add some logg
            return false;
        }

        return true;
    }

    /**
     * add owners to existing list
     *
     * @param DistributionList $distList
     * @param array $owners
     * @return bool
     */
    public function addListOwners(DistributionList $distList, $owners = [])
    {
        /**
         * check if available some owners
         */
        if(!$owners)
        {
            return true;
        }

        /**
         * update list by owners
         */
        foreach ($owners as $owner)
        {
            $distList->addOwner($owner);
        }

        /**
         * add owners to list
         */
        $result = $this->api->distributionList->addOwners($distList);

        if(!$result)
        {

            //todo add some logg
            return false;
        }

        return true;
    }

    /**
     * add aliases to list
     *
     * @param DistributionList $distList
     * @param array $aliases
     * @return bool
     */
    public function addListAliases(DistributionList $distList, $aliases = [])
    {
        foreach ($aliases as $alias)
        {
            $distList->setAlias($alias);
            $result = $this->api->distributionList->addAlias($distList);

            if(!$result)
            {
                //todo logger
            }
        }

        return true;
    }

}