<?php

namespace front;

use email\Email;
use tools\IdnaConvertor;
use domain\DomainAPI;
use model\Bill;
use model\Domain;
use model\DomainOrder;
use model\DomainOwner;
use model\Languages;
use model\Promocode;
use sms\SMS;
use System\Config;
use System\Db\Schema\Schema;
use System\Db\Schema\Table;
use System\Exception;
use System\Notifier;
use System\Router;
use System\Tools;
use System\View\View;

class DomainOrdersController extends FrontController
{

    public function process()
    {
        $config = new Config();
        if(!$config->enable_component_domain){
            Tools::redirect('/');
        }

        parent::process(); // TODO: Change the autogenerated stub
    }

    public function actionValidateAjax(){
        $field = Tools::rPOST('field');
        $val   = Tools::rPOST('value');
        if ($field == "promocode"){
            $promocode = new Promocode();
            $promocode->where("code", $val);
            $promocode= new Promocode($promocode->getRow());
            if($promocode->isAvailable('-2')){
                echo json_encode(['result' => 1]);
            } else {
                echo json_encode(['result' => 0]);
            }
        }
    }

    public function actionListAjax()
    {
        $this->layout->import('content', $v = $this->getView('domain/order/list.php'));
        $DomainOrder = new DomainOrder;

        $order       = Tools::rPOST('order');
        if (isset($order['field']) && $order['field'] && $order['type']) {
            $DomainOrder->order($order['field'], $order['type']);
        } else {
            $DomainOrder->order('id', 'desc');
        }

        $filter  = Tools::rPOST('filter');
        $vfilter = array();
        if (isset($filter) && $filter != '') {
            foreach ($filter as $field => $option) {
                $value           = Tools::clearXSS($option['value']);
                $type            = isset($option['type']) ? $option['type'] : 'like';
                $vfilter[$field] = $value;
                if ($field && $value != '') {
                    if ($type == 'like') {
                        $DomainOrder->where($field, 'LIKE', '%' . $value . '%');
                    } else if ($type == 'equal') {
                        $DomainOrder->where($field, $value);
                    }
                }
            }
        }
        $DomainOrder->where('client_id', $this->client->id);

        $DomainOrder->limit($this->from, $this->count);
        $v->filter = $vfilter;
        $v->orders = $DomainOrder->getRows();


        $this->pagination($DomainOrder->lastQuery()->getRowsCount());
    }


    public function actionList()
    {
        $view = $this->getView('empty-ajax-block.php');
        $this->layout->import('content', $view);


    }

    public function actionOrder()
    {

        if (Router::getParam('ids')) {

            if (Tools::rPOST('order')) {
                $orders  = Tools::rPOST('order');
                $periods = Tools::rPOST('period');
                $owners  = Tools::rPOST('owner_id');

                $ns1 = Tools::rPOST('ns1');
                $ns2 = Tools::rPOST('ns2');
                $ns3 = Tools::rPOST('ns3');
                $ns4 = Tools::rPOST('ns4');


                $bills_ids = array();
                $errors    = array();

                foreach ($orders as $id_order) {
                    $DomainOrder = new DomainOrder($id_order);
                    $DomainOrder->client_id = $this->client->id;

                    if (!$owners[$id_order]) {
                        $errors[] = (object)['type' => 'no_selected_owner'];
                        break;
                    }

                    if (!$ns1[$id_order] || !$ns2[$id_order]) {
                        $errors[] = (object)['type' => 'no_selected_ns'];
                        break;
                    }
                    $DomainOrder->owner_id  = $owners[$id_order];

                    $DomainOwner            = new DomainOwner($DomainOrder->owner_id);

                    $domainObject           = new Domain($DomainOrder->domain_id);

                    if ($DomainOwner->type == 1 && ($domainObject->name == 'ru' || $domainObject->name == 'рф')) {
                        if (!$DomainOwner->passport || !$DomainOwner->passport_issued || !$DomainOwner->passport_date) {
                            $errors[] = (object)array('type' => 'owner_reg', 'code' => DomainAPI::ANSWER_CONTACT_CREATE_ERROR_PASSPORT, 'order' => $DomainOrder);
                            break;
                        }
                    }

                    $DomainOrder->date     = date('Y-m-d');
                    $DomainOrder->dns1     = $ns1[$id_order];
                    $DomainOrder->dns2     = $ns2[$id_order];
                    $DomainOrder->dns3     = $ns3[$id_order];
                    $DomainOrder->dns4     = $ns4[$id_order];



                    $rapi        = DomainAPI::getRegistrar($DomainOrder->registrant_id);

                    $contract_id = $rapi->createPerson($DomainOwner);
                    $DomainOrder->contract_id = $contract_id;
                    $nic_hdl = $DomainOrder->nic_hdl;

                    if (!$DomainOrder->nic_hdl) {
                        $nic_hdl = $rapi->createContactPerson($DomainOwner, $contract_id);

                        if ($nic_hdl == DomainAPI::ANSWER_CONTACT_CREATE_FAIL) {
                            $errors[] = (object)array('type' => 'owner_reg', 'code' => $rapi->getErrorCode(), 'order' => $DomainOrder);
                            break;
                        }
                    }


                    $DomainOrder->nic_hdl = $nic_hdl;
                    $DomainOrder->save();
                }

                if (!$errors) {
                    foreach ($orders as $id_order) {
                        $DomainOrder = new DomainOrder($id_order);
                        $Domain      = new Domain($DomainOrder->domain_id);

                        $bill       = new Bill();
                        $bill->client_id       = $this->client->id;
                        $bill->type            = Bill::TYPE_DOMAIN_ORDER;
                        $bill->domain_order_id = $DomainOrder->id;
                        $bill->pay_period      = $periods[$id_order];
                        $bill->price           = $Domain->price;
                        $bill->total           = $bill->pay_period * $Domain->price;
                        $bill->save();

                        Notifier::NewBill($this->client, $bill);
                        Notifier::NewDomainOrder($DomainOrder);

                        $bills_ids[] = $bill->id;
                    }

                    if (count($bills_ids) == 1) {
                        $bill = new Bill($bills_ids[0]);
                    } else {

                        $bill            = new Bill();
                        $bill->inc       = implode('|', $bills_ids);
                        $bill->type      = Bill::TYPE_INC;
                        $bill->client_id = $this->client->id;

                        $total = 0;

                        foreach ($bills_ids as $bill_id) {
                            $b = new Bill($bill_id);
                            $total += $b->total;
                        }

                        //calculate price with promocode discount
                        $promocode  = new Promocode();
                        $promocode  = new Promocode($promocode->where("code", Tools::rPOST("promocode"))->getRow());
                        $total      = $promocode->calcPrice($total, -2);
                        
                        $bill->total = $total;

                        $bill->save();

                    }

                    // print_r($bill); exit;
                    Tools::redirect('bill/' . $bill->id);
                } else {
                    $orders = array();

                    foreach (explode(',', Router::getParam('ids')) as $id_order) {
                        $DomainOrder       = new DomainOrder($id_order);
                        if($DomainOrder->isLoadedObject()) {
                            $DomainOrder->data = new Domain($DomainOrder->domain_id);
                            $orders[] = $DomainOrder;
                        }
                    }


                    if(empty($orders)){
                        Tools::redirect('domain-orders/order?error=1');
                    }

                    $this->layout->import('content', $v = $this->getView('domain/order/period.php'));

                    //  print_r($errors);
                    $v->errors = $errors;
                    $v->orders = $orders;
                    $v->owners = DomainOwner::factory()->where('client_id', $this->client->id)->getRows();
                }
            } else {

                foreach (explode(',', Router::getParam('ids')) as $id_order) {
                    $DomainOrder       = new DomainOrder($id_order);
                    $this->checkAccess($DomainOrder);

                    if($DomainOrder->isLoadedObject()) {
                        $DomainOrder->data = new Domain($DomainOrder->domain_id);
                        $orders[] = $DomainOrder;
                    }
                }

                if(empty($orders)){
                    Tools::redirect('domain-orders/order?error=1');
                }

                $this->layout->import('content', $v = $this->getView('domain/order/period.php'));
                $v->orders = $orders;
                $v->owners = DomainOwner::factory()->where('client_id', $this->client->id)->getRows();
            }
        } else {

            if(Router::getParam('domains')){
                $domains     = Router::getParam('domains');
                $orders    = array();
                $order_ids = array();

                foreach (explode(',', $domains) as $domain) {


                    $domain = trim($domain);
                    $domain = str_replace(' ','', $domain);

                    $domain = Tools::clearXSS($domain);


                    $res = array();
                    //$domain = mb_strtolower($domain);

                    preg_match('/\.(.*)/', $domain, $res);

                    if(!isset($res[1])){
                        continue;
                    }

                    $domain_zone = $res[1];

                    $Domain = new Domain();
                    $domainObject = $Domain->where('name', $domain_zone)->getRow();


                    if(!$domainObject){
                        Tools::redirect('domain-orders/order?error=1');
                        exit();
                    }

                    try {
                        $rapi = DomainAPI::getRegistrar($domainObject->registrant_id);
                    } catch (Exception $e) {
                        Tools::redirect('domain-orders/order?error=1');
                    }

                    $check_domain = $rapi->checkDomainAvailable($domain) ;
                    if($check_domain == DomainAPI::ANSWER_DOMAIN_AVAILABLE) {
                        $DomainOrder = new DomainOrder();
                        $DomainOrder->client_id = $this->client->id;
                        $DomainOrder->domain = $domain;
                        $DomainOrder->domain_id = $domainObject->id;
                        $DomainOrder->registrant_id = $domainObject->registrant_id;
                        $DomainOrder->save();
                        $order_ids[] = $DomainOrder->id;
                    }
                }

                Tools::redirect('domain-orders/order/' . implode(',', $order_ids));
            }

            if (Tools::rPOST('sell')) {

                $sells     = Tools::rPOST('sell');
                $orders    = array();
                $order_ids = array();

                foreach ($sells as $sell) {
                    $registrant_id              = Tools::rPOST('registrant_id')[$sell];
                    $domain_id                  = Tools::rPOST('domain_id')[$sell];
                    $DomainOrder                = new DomainOrder();
                    $DomainOrder->client_id     = $this->client->id;
                    $DomainOrder->domain        = $sell;
                    $DomainOrder->domain_id     = $domain_id;
                    $DomainOrder->registrant_id = $registrant_id;
                    $DomainOrder->save();


                    $order_ids[] = $DomainOrder->id;

                }

                Tools::redirect('domain-orders/order/' . implode(',', $order_ids));


            } else {

                $this->layout->import('content', $v = $this->getView('domain/order/check.php'));
                $domains_res = array(
                    'available'    => array(),
                    'booked'       => array(),
                    'orders'       => array(),
                    'no_available' => array()
                );


                if (Tools::rPOST('domain')) {

                    $domains = explode(',', Tools::rPOST('domain'));

                    $domains = str_replace('http://', '', $domains);
                    $domains = str_replace('https://', '', $domains);

                    foreach ($domains as $domain) {

                        $Domain = new Domain();
                        if (!strpos($domain, '.')) {
                            foreach ($Domain->getRows() as $d) {
                                $domains[] = $domain . '.' . $d->name;
                            }

                        }
                    }
                    $domains_by_registrar = array();

                    foreach ($domains as $domain) {
                        $domain = trim($domain);
                        $domain = str_replace(' ','', $domain);
                        $domain = Tools::clearXSS($domain);

                        $res = array();
                        //$domain = mb_strtolower($domain);

                        preg_match('/\.(.*)/', $domain, $res);

                        if(!isset($res[1])){
                            continue;
                        }

                        $domain_zone = $res[1];


                        $domain_registrant = $Domain->where('name', $domain_zone)->getRow();
                        if(!isset($domain_registrant->registrant_id)){
                            $domains_by_registrar[0][] = $domain;
                            continue;
                        }
                        $domains_by_registrar[$domain_registrant->registrant_id][] = $domain;
                    }

                    foreach ($domains_by_registrar as $domain_registrant_id => $domains){


                        if($domain_registrant_id){
                            try {
                                $rapi = DomainAPI::getRegistrar($domain_registrant_id);
                            } catch (Exception $e) {
                                Tools::redirect('domain-orders/order?error=1');
                            }

                            try {

                                $check_domains = $rapi->checkDomainsAvailable($domains) ;

                                //print_r($check_domains);
                                foreach ($check_domains as $domain => $check_domain){

                                    $domain = trim($domain);
                                    $res = array();

                                    preg_match('/\.(.*)/', $domain, $res);

                                    if(!isset($res[1])){
                                        continue;
                                    }

                                    $domain_zone = $res[1];

                                    $Domain = new Domain();
                                    $domain_registrant = $Domain->where('name', $domain_zone)->getRow();

                                    if ($check_domain == DomainAPI::ANSWER_DOMAIN_AVAILABLE) {
                                        if (!DomainOrder::factory()->where('domain', $domain)->where('status', '!=', -1)->getRow()) {
                                            $domains_res['available'][$domain] = $domain_registrant;
                                        } else {
                                            $domains_res['orders'][$domain] = $domain_registrant;
                                        }
                                    } else {
                                        if (!DomainOrder::factory()->where('domain', $domain)->getRow()) {
                                            $domains_res['booked'][$domain] = $domain_registrant;
                                        } else {
                                            $domains_res['orders'][$domain] = $domain_registrant;
                                        }

                                    }
                                }
                            } catch(Exception $e){

                            }
                        } else{
                            foreach ($domains as $domain) {
                                $domains_res['no_available'][$domain] = 0;
                            }
                        }
                    }

                }


                $v->domains = Domain::factory()->getRows();
                $v->res     = $domains_res;
            }
        }
    }


    public function actionChangeNSAjax()
    {
        $id_order = Tools::rGET('id_order');

        $DomainOrder = new DomainOrder($id_order);

        if ($DomainOrder->client_id != $this->client->id) {
            Tools::display403Error();
        }

        if (Tools::rPOST()) {

            $old_ns = array(
                $DomainOrder->dns1 => $DomainOrder->ip1,
                $DomainOrder->dns2 => $DomainOrder->ip2,
                $DomainOrder->dns3 => $DomainOrder->ip3,
                $DomainOrder->dns4 => $DomainOrder->ip4
            );

            $DomainOrder->dns1 = Tools::rPOST('dns1');
            $DomainOrder->dns2 = Tools::rPOST('dns2');
            $DomainOrder->dns3 = Tools::rPOST('dns3');
            $DomainOrder->dns4 = Tools::rPOST('dns4');

            if($DomainOrder->status == 2 ){
                $DomainOrder->save();
                $this->returnAjaxAnswer(1, 'NS сервера были изменены');
            }

            $res = DomainAPI::getRegistrar($DomainOrder->registrant_id)->changeNS($DomainOrder, $old_ns);

            if ($res == DomainAPI::ANSWER_DOMAIN_CHANGE_NS_SUCCESS) {
                $DomainOrder->save();
                $this->returnAjaxAnswer(1, 'NS сервера успешно изменены');
            }
            $this->returnAjaxAnswer(1, 'Не удалось сменить NS сервера, возможно домен находится на стадии обработки, попробуйте повторить операцию позже!');

        }

        $this->layout->import('content', $v = $this->getView('domain/order/change-ns.php'));
        $v->order = $DomainOrder;

    }

    public function actionProlongAjax()
    {
        $id_order    = Tools::rGET('id_order');
        $DomainOrder = new DomainOrder($id_order);

        if ($DomainOrder->client_id != $this->client->id) {
            Tools::display403Error();
        }

        $DomainOrder->period = 1;
        $DomainOrder->save();

        $Domain = new Domain($DomainOrder->domain_id);

        $Bill                  = new Bill();
        $Bill->price           = $Domain->extension_price;
        $Bill->total           = $Domain->extension_price;
        $Bill->type            = Bill::TYPE_DOMAIN_PROLONG;
        $Bill->domain_order_id = $DomainOrder->id;
        $Bill->client_id       = $this->client->id;
        $Bill->save();

        Notifier::NewBill($this->client, $Bill);

    }

    public function actionProlong()
    {
        $id_order    = Tools::rGET('id_order');

        $Bill = new Bill();
        $bill_exist = $Bill->where('domain_order_id', $id_order)->where('is_paid', 0)->getRowsCount();



        if(Tools::rPOST()){
            $DomainOrder = new DomainOrder($id_order);
            $DomainOrder->period = Tools::rPOST('pay_period');
            $DomainOrder->save();

            if ($DomainOrder->client_id != $this->client->id) {
                Tools::display403Error();
            }

            $Domain = new Domain($DomainOrder->domain_id);

            $Bill                  = new Bill();
            $Bill->price           = $Domain->extension_price;
            $Bill->total           =  Tools::rPOST('pay_period') * $Domain->extension_price;
            $Bill->type            = Bill::TYPE_DOMAIN_PROLONG;
            $Bill->domain_order_id = $DomainOrder->id;
            $Bill->client_id       = $this->client->id;
            $Bill->pay_period     = Tools::rPOST('pay_period');
            $Bill->save();

            Notifier::NewBill($this->client, $Bill);

            Tools::redirect('bill/'.$Bill->id);
        }


        $DomainOrder = new DomainOrder($id_order);
        $this->layout->import('content', $v = $this->getView('domain/order/prolong.php'));
        $v->order  = $DomainOrder;
        $v->domain = new Domain($DomainOrder->domain_id);
        $v->error = '';
        if ($bill_exist > 0) {
            $v->error = ('bill_exist');
        }

    }

    public function actionOrderAjax()
    {
        $this->actionOrder();

    }

    public function actionRemoveAjax()
    {
        $id_order    = Tools::rGET('id_order');
        $DomainOrder = new DomainOrder($id_order);

        if ($DomainOrder->client_id != $this->client->id) {
            $this->returnAjaxAnswer(0, 'Доступ запрещен');
        }

        $DomainOrder->remove();
        $this->returnAjaxAnswer(1, 'Заказ отменен');


    }
}