<?php

namespace MGModule\DNSManager2\mgLibs\custom\helpers;

use MGModule\DNSManager2\controllers\addon\admin\zones;
use MGModule\DNSManager2\mgLibs\custom\manager\ClientHelper;
use MGModule\DNSManager2\mgLibs\MySQL\result;
use \MGModule\DNSManager2\models\custom\globalsetting;
use MGModule\DNSManager2\models\custom\zone\ZoneTypeEnum;
use MGModule\DNSManager2\models\whmcs\addon\addon;
use MGModule\DNSManager2\models\whmcs\domains\domain;
use MGModule\DNSManager2\models\whmcs\domains\repository;
use MGModule\DNSManager2\models\whmcs\hostingaddon\hostingaddon;
use MGModule\DNSManager2\models\whmcs\service\service;

/**
 * Class Zone
 *
 * @author Artur Pilch <artur.pi@modulesgarden.com>
 */
class ZoneSettings
{

    CONST ALLOW_ONLY_DOMAINS_FROM_DOMAINS_ITEMS = 'allowOnlyDomainsFromDomainItems';
    CONST ALLOW_ONLY_DOMAINS_FROM_PRODUCT_ITEMS = 'allowOnlyDomainFromProductItems';
    CONST ALLOW_ONLY_DOMAINS_FROM_DOMAINS_AND_PRODUCT_ITEMS = 'allowOnlyDomainsFromDomainAndProductItems';
    CONST ALLOW_CUSTOM_DOMAINS = 'allowCustomDomain';

    CONST ALLOW_ONLY_THAT_DOMAIN = 'allowOnlyThatDomain';
    CONST ALLOW_ONLY_THAT_PRODUCT_DOMAIN = 'allowOnlyThatProductDomain';


    private static $usedZones = [];

    /**
     * Sponsored Custom Zones Options
     */
    public static function getSettingsForZonesCreate()
    {
        $basics = [
            SELF::ALLOW_ONLY_DOMAINS_FROM_DOMAINS_ITEMS,
            SELF::ALLOW_ONLY_DOMAINS_FROM_PRODUCT_ITEMS,
            SELF::ALLOW_ONLY_DOMAINS_FROM_DOMAINS_AND_PRODUCT_ITEMS,
            SELF::ALLOW_CUSTOM_DOMAINS,
        ];

        $vars[globalsetting\GlobalSettingEnum::DOMAIN_ITEM_OPTION] = [
            SELF::ALLOW_ONLY_THAT_DOMAIN,
        ];

        $vars[globalsetting\GlobalSettingEnum::PRODUCT_ITEM_OPTION] = [
            SELF::ALLOW_ONLY_THAT_PRODUCT_DOMAIN,
        ];

        $vars[globalsetting\GlobalSettingEnum::ADDON_ITEM_OPTION] = [
            SELF::ALLOW_ONLY_THAT_PRODUCT_DOMAIN,
        ];

        $vars[globalsetting\GlobalSettingEnum::OTHER_ITEM_OPTION] = [];

        foreach ($vars as &$item)
        {
            $item = array_merge($item, $basics);
        }

        return $vars;
    }

    public static function getZoneItemSettingForType($type)
    {
        switch ($type)
        {
            case ZoneTypeEnum::OTHER:
                return self::getSettingFromQuery(globalsetting\GlobalSettingEnum::OTHER_ITEM_OPTION);
            case ZoneTypeEnum::DOMAIN:
                return self::getSettingFromQuery(globalsetting\GlobalSettingEnum::DOMAIN_ITEM_OPTION);
            case ZoneTypeEnum::HOSTING:
                return self::getSettingFromQuery(globalsetting\GlobalSettingEnum::PRODUCT_ITEM_OPTION);
            case ZoneTypeEnum::ADDON:
                return self::getSettingFromQuery(globalsetting\GlobalSettingEnum::ADDON_ITEM_OPTION);
        }
    }

    public static function getProperlyItems($clientid, $relId, $relType)
    {
        $setting = self::getZoneItemSettingForType($relType)->value;

        switch ($setting)
        {
            case self::ALLOW_CUSTOM_DOMAINS:
                return self::ALLOW_CUSTOM_DOMAINS;

            case self::ALLOW_ONLY_THAT_DOMAIN:
            case self::ALLOW_ONLY_THAT_PRODUCT_DOMAIN:
                $domain = self::getOneDomain($relId, $relType)->domain;
                $domain = !in_array($domain, self::getUsedZones()) ? $domain : '';
                return [$domain];

            case self::ALLOW_ONLY_DOMAINS_FROM_DOMAINS_AND_PRODUCT_ITEMS:
                $records = array_merge(self::getAllDomainsFromDomainsRecords($clientid), self::getAllDomainsFromHostingRecords($clientid));
                asort($records);
                return $records;

            case self::ALLOW_ONLY_DOMAINS_FROM_DOMAINS_ITEMS:
                return self::getAllDomainsFromDomainsRecords($clientid);

            case self::ALLOW_ONLY_DOMAINS_FROM_PRODUCT_ITEMS;
                return self::getAllDomainsFromHostingRecords($clientid);


        }

        return false;
    }

    public static function getOneDomain($relId, $relType)
    {
        switch ($relType)
        {
            case ZoneTypeEnum::DOMAIN:
                return domain::factory($relId);

            case ZoneTypeEnum::HOSTING:
                return service::factory($relId);

            case ZoneTypeEnum::ADDON:
                return hostingaddon::factory($relId)->getHostingModel();
        }

        return false;
    }

    public static function getSettingFromQuery($key)
    {
        return globalsetting\Repository::factory()->byKey($key)->one();
    }

    public static function isDomainClient($zoneName, $type, $relid, $clientId)
    {
        $setting = self::getZoneItemSettingForType($type)->value;
        switch ($setting)
        {
            case self::ALLOW_CUSTOM_DOMAINS:
                return true;

            case self::ALLOW_ONLY_THAT_DOMAIN:
            case self::ALLOW_ONLY_THAT_PRODUCT_DOMAIN:
                $model = self::getOneDomain($relid, $type);
                return $model->domain == $zoneName && $model->userid == $clientId;

            case self::ALLOW_ONLY_DOMAINS_FROM_DOMAINS_AND_PRODUCT_ITEMS:
                $domains = array_merge(self::getAllDomainsFromDomainsRecords($clientId), self::getAllDomainsFromHostingRecords($clientId));
                return in_array($zoneName, $domains);

            case self::ALLOW_ONLY_DOMAINS_FROM_DOMAINS_ITEMS:
                return in_array($zoneName, self::getAllDomainsFromDomainsRecords($clientId));

            case self::ALLOW_ONLY_DOMAINS_FROM_PRODUCT_ITEMS;
                return in_array($zoneName, self::getAllDomainsFromHostingRecords($clientId));
        }
        return false;
    }

    public static function getAllDomainsFromHostingRecords($clientid)
    {
        $services = \MGModule\DNSManager2\models\whmcs\service\repository::factory()->byClientID($clientid)->get();

        $out = [];
        foreach ($services as $serviceModel)
        {
            $domain = $serviceModel->domain;
            if(!self::canAddZone($domain, $out))
            {
                continue;
            }
            array_push($out, $domain);
        }
        asort($out);

        return $out;
    }


    public static function getAllDomainsFromDomainsRecords($clientid)
    {

        $domains = repository::factory()->byClientID($clientid)->get();

        $out = [];
        foreach ($domains as $domainModel)
        {
            $domain = $domainModel->domain;
            if(!self::canAddZone($domain, $out))
            {
                continue;
            }
            array_push($out, $domain);
        }
        asort($out);

        return $out;
    }

    private static function canAddZone($domain, $domains)
    {
        if(!$domain ||  trim($domain) == '')
        {
            return false;
        }

        if(self::isExcludeUsedZones() && in_array($domain, self::getUsedZones()))
        {
            return false;
        }
        if(in_array($domain, $domains))
        {
            return false;
        }

        if(self::isSubdomain($domain))
        {
            return false;
        }

        return true;
    }

    private static function isSubdomain($domain)
    {
        $helper = new DomainHelper($domain);

        return $helper->isSubdamain();
    }

    public static function getUsedZones()
    {
        if(!empty(self::$usedZones))
        {
            return self::$usedZones;
        }

        $zones = \MGModule\DNSManager2\models\custom\zone\Repository::factory()->get();

        foreach ($zones as $zone)
        {
            array_push(self::$usedZones, $zone->name);
        }

        return self::$usedZones;
    }

    private function isExcludeUsedZones()
    {
        return globalsetting\GlobalSetting::byKey(globalsetting\GlobalSettingEnum::EXCLUDE_USED_ZONE_FROM_OPTIONS)->value == 'on';
    }

}