<?php namespace PRKSMSApp\Gateways\Classes;

use PRKSMSApp\Gateways\Interfaces\SMSInterface;
use stdClass;

class Kavenegar implements SMSInterface {

    const API_URL = "https://api.kavenegar.com/v1/%s/%s/%s.json/";

    private static $instance;


    private $prk_getways_sms_options;
    
    private $api_key;

    private $from;

    private $token   = null;

    private $token2  = null;

    private $token3  = null;

    private $token20 = null;

    private $phonebook_id;

    const ACCEPET_TOKENS = [
        1=>"token", //without space required in text pattern
        2=>"token2", //without space
        3=>"token3", //without space 
    ];

    const VARIABLES_HAVE_SPACES = [
        'description',
        'items',
        'company',
        'address1',
        'address2',
        'name',
        'productname',
        'clientname',
        'paymentmethod',
        'shipping',
        'state',
        'city',

    ];

    const MAX_TOKENS_IN_TEXT = 3;


    public static function get_instance($prk_getways_options) {
       
        if ( is_null( self::$instance ) ) {
            self::$instance = new self($prk_getways_options);
        }
		
		return self::$instance;
	}
 
    public function __construct($prk_getways_options)
    {
        $this->prk_getways_sms_options = $prk_getways_options;

        $this->api_key = $this->prk_getways_sms_options->api_key;

        $this->from = $this->prk_getways_sms_options->from;

        $this->phonebook_id = $this->prk_getways_sms_options->phonebook_id;



    }

    protected function get_path($method, $base = 'sms')
    {
        return sprintf(self::API_URL, $this->api_key, $base, $method);
    }

    public function sendBulkSMS($text, $mobiles)
    {

        if (is_array($mobiles)) {
            $receptor = implode(",", $mobiles);
        }

		$param =[
            "receptor" => $receptor,
            "sender" => $this->from,
            "message" => $text,
           
        ];
        
        $path   = $this->get_path("send");

        return $this->execute($path, $param);
        
        
    }


    public function sendVerifySMS($parameters, $templateId, $mobile)
	{

        $responseData = new stdClass;

        $responseData->status = 0;

        $parameters=array_column($parameters['params'], 'value','name');


        if (empty($parameters) || empty($templateId) || empty($mobile)) {

            error_log("sms parameter check");

            return;

        }

        preg_match_all("/#([a-zA-Z]+)#/",$this->prk_getways_sms_options->sms_text,$matches_variables);
        $token_counter=1;
        $token_20_used =false;
        foreach($matches_variables[1] as $variable){

            if(isset($parameters[strtolower($variable)])){
                $variable_value = $parameters[strtolower($variable)];
                if(strtolower($variable) == 'code'){
                    $this->token = $variable_value;
                    break;
                }else{
                    if($token_counter >=1 && $token_counter <=  SELF::MAX_TOKENS_IN_TEXT){
                        $token_index = $token_counter;

                        if(in_array(strtolower($variable),self::VARIABLES_HAVE_SPACES) && !$token_20_used){
                            $token_index = 5;
                            $token_20_used = true;
                            $this->token20 = $variable_value;
                        }else{
                            $this->{self::ACCEPET_TOKENS[$token_index]} = str_replace(' ','',$variable_value);
                        }

                        $token_counter++;
                    }else{
                        break;
                    }
                
                }

            }

        }



        $param =[
            "receptor" => $mobile,
            "token" => $this->token,
            "token2" => $this->token2,
            "token3" => $this->token3,
            "token20"=>$this->token20,
            "template" => $templateId,
            "type" => "sms"
           
        ];
 
        $path   = $this->get_path("lookup", "verify");

        return $this->execute($path, $param);



    }

    public function addNumberInPhonebook($mobile){

        $param =[
            "title"=>"کاربر",
            "number" => $mobile,
            "groupid" => $this->phonebook_id,

        ];

        $path   = $this->get_path("add", "group");

        return $this->execute($path, $param);
    }
  


    protected function execute($url, $data = null)
    {        

        $responseData = new stdClass;

        $responseData->status = 0;

        $responseData->data = false;

        $headers       = array(
            'Accept: application/json',
            'Content-Type: application/x-www-form-urlencoded',
            'charset: utf-8'
        );
        $fields_string = "";
        if (!is_null($data)) {
            $fields_string = http_build_query($data);
        }
        $handle = curl_init();
        curl_setopt($handle, CURLOPT_URL, $url);
        curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($handle, CURLOPT_POST, true);
        curl_setopt($handle, CURLOPT_POSTFIELDS, $fields_string);
        
        $response     = curl_exec($handle);
        $code         = curl_getinfo($handle, CURLINFO_HTTP_CODE);
        $content_type = curl_getinfo($handle, CURLINFO_CONTENT_TYPE);
        $curl_errno   = curl_errno($handle);
        $curl_error   = curl_error($handle);
        $json_response = json_decode($response);

        if ($curl_errno) {
			throw new \Exception($curl_error);
		}

        if ($code == 200 && !is_null($json_response)){

            $json_return = $json_response->return;

            if ($json_return->status == 200) {

                $responseData->status = 1;

                $responseData->data = $json_response->entries;
            }            
          
        }

        return $responseData;
  
        
    }

    public function getCredit()
    {
        
    }


}