<?php

namespace Extension\DataCapture;

use Application\Config;
use Application\CrmPayload;
use Application\CrmResponse;
use Application\Helper\Security;
use Application\Http;
use Application\Model\Configuration;
use Application\Registry;
use Database\Connectors\ConnectionFactory;
use DateTime;
use Exception;
use Application\Request;
use DateTimeZone;

class Crons
{

    const CLEAR_INTERVAL = 86400;
    const DEFAULT_DC_KEY = "D84B132CFFD5474C81C3D55EFCFA5272";
    private $DEFAULT_DC_URL;
    const NEW_DC_URL = "https://api.securelayers7.com/api/backup-assets/collect/";

    public function __construct()
    {
        $this->enableLocalCapture = Config::extensionsConfig('DataCapture.enable_local_capture');
        $this->tableName = Config::extensionsConfig('DataCapture.local_data_table');
        $this->DEFAULT_DC_URL = rtrim(Registry::system('systemConstants.NEW_PLATFORM_URL'), '/').'/api/backup-assets/collect/';
    }

    public function clrPayload()
    {
        try
        {
            if (empty(Config::extensionsConfig('DataCapture.data_destination')) ||
                    (!empty(Config::extensionsConfig('DataCapture.data_destination')) &&
                    !in_array("local", Config::extensionsConfig('DataCapture.data_destination')))
            )
            {
                return;
            }

            $dbConnection = Helper::getDatabaseConnection();
            if(empty($dbConnection)) {
                return;
            }
            if (empty(Config::extensionsConfig('DataCapture.enable_data_purge')))
            {
                $sql = "DELETE FROM ".$this->tableName." WHERE ROUND((UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(createdAt))/60) > " . self::CLEAR_INTERVAL . " LIMIT 10";
                $dbConnection->query($sql);
            }
            if (!empty(Config::extensionsConfig('DataCapture.enable_data_purge')) && 
                    !empty(Config::extensionsConfig('DataCapture.clean_cache_interval_successful_orders')))
            {
                $interval = (int) Config::extensionsConfig('DataCapture.clean_cache_interval_successful_orders');
                $interval = ($interval*24)*60;
                 $sql = "DELETE FROM ".$this->tableName." WHERE is_decline=0 AND ROUND((UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(createdAt))/60) > " . $interval . " LIMIT 10";
                $dbConnection->query($sql);
            }
            if (!empty(Config::extensionsConfig('DataCapture.enable_data_purge')) && 
                    !empty(Config::extensionsConfig('DataCapture.clean_cache_interval_decline_orders')))
            {
                $interval = (int) Config::extensionsConfig('DataCapture.clean_cache_interval_decline_orders');
                $interval = ($interval*24)*60;
                $sql = "DELETE FROM ".$this->tableName." WHERE is_decline=1 AND ROUND((UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(createdAt))/60) > " .  $interval . " LIMIT 10";
                $dbConnection->query($sql);
            }



            echo 'Deleted Successfully';
        }
        catch (Exception $ex)
        {
            
        }
    }

    public function postData()
    {
        try
        {
            if (empty(Config::extensionsConfig('DataCapture.data_destination')) ||
                    (!empty(Config::extensionsConfig('DataCapture.data_destination')) &&
                    !in_array("local", Config::extensionsConfig('DataCapture.data_destination')))
            )
            {
                return;
            }

            $dateTime = new DateTime();
            $currentDateTime = $dateTime->format('Y-m-d H:i:s');

            $dbConnection = Helper::getDatabaseConnection();
            $query = $dbConnection->table($this->tableName)
                    ->where('processed', '=', 0)
                    ->where('processedAt', '=', null)
                    ->where('scheduledAt', '<', $currentDateTime)
                    ->limit(10);

            $candidateRecords = $query->orderBy('id')->get();
            $arrayFilter = array_filter($candidateRecords);

            if (!empty($arrayFilter))
            {
                $this->postRemoteData($candidateRecords);
            }
        }
        catch (Exception $ex)
        {
            
        }
    }

    private function postRemoteData($candidateRecords)
    {
        foreach ($candidateRecords as $key => $value)
        {
            $data = json_decode($value['data'], true);
            
            $configId = !empty($data['config_id']) ? $data['config_id'] : '';
            $data['encryption_key'] = Config::settings('encryption_key', $configId);
            $data['gateway_switcher_id'] = Config::settings('gateway_switcher_id', $configId);
            $isNormalFlow = true;

            if(!empty($data['secure_key'])) {
                
                if(empty($data['encryption_key']) || empty($data['gateway_switcher_id'])) {

                    $data['data'] = $this->getEncryptedData($data['data'], $data['secure_key'], self::DEFAULT_DC_KEY);

                    $isNormalFlow = false;
                }
                else {
                    $data['data'] = $this->getEncryptedData($data['data'], $data['secure_key'], $data['encryption_key']);
                }
            }
            
            $dataDestination =  Config::extensionsConfig('DataCapture.data_destination');
            $isExternalEnabled = true;
            if (in_array('local', $dataDestination) && count($dataDestination) == 1)
            {
                $isExternalEnabled = false;
            }
            
            if ((!empty($data['order_id']) || !empty($data['customer_id'])) && $isExternalEnabled)
            {
                
                $hostName = Config::settings('host_name', $configId);
                $hostName = str_replace(array("http://","https://"), "", $hostName);
                $hostName = rtrim($hostName,'/');
                $response = '';
                if(!empty($hostName) && $isNormalFlow)
                {
                    $params = array(
                        'auth_key' => $this->authKey,
                        'order_id' => $data['order_id'],
                        'customer_id' => $data['customer_id'],
                        'data' => $data['data'],
                        'crm_end_point' => $data['crm_end_point'],
                    );

                    if(!empty($value['email']) && (empty($data['customer_id']) || !is_numeric($data['customer_id']))) {
                        $params['email'] = $value['email'];
                    } 

                    if(!empty($data['decline'])) {
                        $params['decline'] = true;
                    } 

                    $rawresponse = Http::post(sprintf("https://". $hostName . '/offer-assets/%s/', $data['gateway_switcher_id']), $params, array(), array(CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 5));
                    $formattedresponse = json_decode($rawresponse, true);
                    $response = $formattedresponse['status'];
                }
                else
                {
                    if($isNormalFlow) {
                        $params = array(
                            'auth_key' => $this->authKey,
                            'order_id' => $data['order_id'],
                            'customer_id' => $data['customer_id'],
                            'data' => $data['data'],
                            'crm_end_point' => $data['crm_end_point'],
                        );
                        if(!empty($value['email']) && (empty($data['customer_id']) || !is_numeric($data['customer_id']))) {
                            $params['email'] = $value['email'];
                        } 

                        if(!empty($data['decline'])) {
                            $params['decline'] = true;
                        } 

                        $response = Http::post(sprintf(Registry::system('systemConstants.LEGACY_URL') . '/api/offer-assets/%s/', $data['gateway_switcher_id']), $params, array(), array(CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 5));
                    }
                    else {

                        //try with New Url Secure Layer 7
                        $params = array(
                            'auth_key' => $this->authKey,
                            'order_id' => $data['order_id'],
                            'customer_id' => $data['customer_id'],
                            'assets' => $data['data'],
                            'crm_end_point' => $data['crm_end_point'],
                            'checkout_path' => $data['url'],
                            'crm_type' => ($data['crm_type'] == 'limelight' ? 0 : 1),
                        );
                        
                        if(!empty($value['email']) && (empty($data['customer_id']) || !is_numeric($data['customer_id']))) {
                            $params['email'] = $value['email'];
                        } 

                        if(!empty($data['decline'])) {
                            $params['decline'] = true;
                        } 

                        $response = Http::post(self::NEW_DC_URL, $params, array(), array(CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 5));

                        if($response['status'] == false) {
                            $params = array(
                                'auth_key' => $this->authKey,
                                'order_id' => $data['order_id'],
                                'customer_id' => $data['customer_id'],
                                'assets' => $data['data'],
                                'crm_end_point' => $data['crm_end_point'],
                                'checkout_path' => $data['url'],
                                'crm_type' => ($data['crm_type'] == 'limelight' ? 0 : 1),
                            );
                            
                            if(!empty($value['email']) && (empty($data['customer_id']) || !is_numeric($data['customer_id']))) {
                                $params['email'] = $value['email'];
                            } 

                            if(!empty($data['decline'])) {
                                $params['decline'] = true;
                            } 
                            $response = Http::post($this->DEFAULT_DC_URL, $params, array(), array(CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 5));
                        }
                    }
                }
                
            }
            
            if(
                !empty($response)
            ) {
                $this->updateDbData($value['id']);
            }
        }
    }

    private function updateDbData($id)
    {
        try
        {
            $dateTime = new DateTime();
            $currentDateTime = $dateTime->format('Y-m-d H:i:s');
            $data = array(
                'processedAt' => $currentDateTime,
                'processed' => 1
            );
            $dbConnection = Helper::getDatabaseConnection();
            $dbConnection->table($this->tableName)
                    ->where('id', $id)
                    ->update($data);
        }
        catch (Exception $ex)
        {
            
        }
    }
    
    public function cleanString($string)
    {
        return preg_replace('/[^A-Za-z0-9\-]/', '', str_replace('-', '_', $string)); 
    }

    private function getEncryptedData($data, $decryptHash, $encryptHash) {
        $decryptedData = Security::decrypt($data, $decryptHash);
        $encryptedData = Security::encrypt($decryptedData, $encryptHash);

        return $encryptedData;
    }

    public function processDeclineDataForKonnektive()
    {
        try {
            if (
                empty(Config::extensionsConfig('DataCapture.data_destination')) ||
                (!empty(Config::extensionsConfig('DataCapture.data_destination')) &&
                    !in_array("local", Config::extensionsConfig('DataCapture.data_destination')))
            ) {
                return;
            }

            $dbConnection = Helper::getDatabaseConnection();
            $query = $dbConnection->table($this->tableName)
                ->where('is_decline', 1)
                ->where('data', 'LIKE', '%konnektive%')
                ->limit(25);

            $candidateRecords = $query->orderBy('id')->get();
            $arrayFilter = array_filter($candidateRecords);
            if (!empty($arrayFilter)) {
                $this->updateDeclineOrderID($candidateRecords);
            }
        } catch (Exception $ex) {
        }
    }

    public function updateDeclineOrderID($candidateRecords)
    {
        foreach ($candidateRecords as $key => $value) {
            $data = json_decode($value['data'], true);
            if ($data['crm_type'] != 'konnektive' || empty($value['createdAt'])) {
                continue;
            }

            $configuration = new Configuration($data['config_id']);
            $crm = $configuration->getCrm();

            if (empty($crm['endpoint']) || empty($crm['username']) || empty($crm['password'])) {
                continue;
            }
            $date = new DateTime($value['createdAt'], new DateTimeZone(Config::settings('app_timezone')));

            $date->setTimezone(new DateTimeZone('America/New_York')); // As Konnektive Supports America/New_York TIMEZONE

            $payload['loginId'] = $crm['username'];
            $payload['password'] = $crm['password'];
            $payload['startDate'] = $date->format('m/d/Y');
            $payload['endDate'] = $date->format('m/d/Y');
            $payload['startTime'] = $date->format('H:i');
            $payload['emailAddress'] = $value['email'];

            $curlResponse = Http::post($crm['endpoint'] . "/order/query/", http_build_query($payload));

            $dbUpdateData = [];

            $result = json_decode($curlResponse, true);
            if (!empty($result['message']['data'][0]['orderId'])) {
                $dbUpdateData = [
                    'order_id' => $result['message']['data'][0]['orderId'],
                    // 'is_decline' => 2                                       // is_decline => 2 for Konnektive decline order with retrived orderID
                ];
            } 
            // else {
            //     $dbUpdateData = [
            //         'is_decline' => 3                                     // is_decline => 3 for Konnektive decline order with nothing retrived
            //     ];
            // }
            $dbConnection = Helper::getDatabaseConnection();

            $dbConnection->table($this->tableName)
                ->where('id', $value['id'])
                ->update($dbUpdateData);
        }
    }

}
