<?php
namespace Models;

class paymaster_qr {
	public $f3, $sets, $config, $web;

	public $errors=array(
		'validation_error'=>'Некорректный запрос (неверный формат)',
		'not_authorized'=>'Недостаточно прав для выполнения операции',
		'idempotency_key_violation'=>'Нарушение уникальности ключа (дублирование запроса)',
		'invalid_operation'=>'Запрос отклонен',
		'payment_token_revoked'=>'Платежный токен отозван',
		'payment_token_blocked'=>'Платежный токен временно заблокирован',
	);
	
	function __construct($f3, $sets, $config) {
		$this->f3=$f3;
		$this->sets=$sets;
		$sticker=explode('|', $config['sticker']);
		$config['stickerId']=$sticker[0];
		$config['payload']=$sticker[1];
        $this->config=$config;
        $this->web=\Web::instance();
	}

	static function stickers($data) {
		if(!$data['Token']) {
        	return array(
        		'success'=>false,
        		'txt'=>'Укажите данные для авторизации'
        	);
        }

		$url='https://paymaster.ru/api/v2/stickers?merchantId='.$data['merchantId'];
		$options = array(
			'method'=>'GET',
    		'follow_location'=>1,
    		'header'=>array(
    			'Authorization: Bearer '.$data['Token'],
    			'Content-Type: application/json',
    			'Accept: application/json'
    		),
    		'content'=>json_encode($vars)
		);

		$web=\Web::instance();
		$request=$web->request($url, $options);

		$json=json_decode($request['body'], true);
		if(mb_strpos($request['headers'][0], '200')>0) {
			if(isset($json['code'])) {
				return array(
            		'success'=>false,
            		'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
            	);
			}
            $options=array();
            foreach ($json['items'] as $value) {
            	if(mb_strtolower($value['status'])=='active') $options[]=array($value['paymentPurpose'], $value['id'].'|'.$value['payload']);
            }
            return array(
            	'success'=>true,
            	'options'=>$options
            );
        }
        elseif(mb_strpos($request['headers'][0], '401')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка авторизации в Paymaster'
		    );
        }
        elseif(mb_strpos($request['headers'][0], '500')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка Paymaster'
		    );
        }

        if(is_array($json) && isset($json['code'])) {
        	return array(
	        	'success'=>false,
	        	'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
	        );
        }

        return array(
        	'success'=>false,
        	'txt'=>implode('; ', $request['headers'])
        );
	}

	function cancel_qr($data) {
		$options=array(
			'method'=>'PUT',
			'header'=>array(
				'Authorization: Bearer '.$this->config['Token'],
			),
			'content'=>''
		);

		$request=$this->web->request('https://paymaster.ru/api/v2/payments/'.$data['sbp_order_id'].'/cancel/', $options);
		$json=json_decode($request['body'], true);
		if(mb_strpos($request['headers'][0], '200')>0) {
        	return array(
        		'success'=>true,
        	);
        }
        elseif(mb_strpos($request['headers'][0], '401')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка авторизации в Paymaster'
		    );
        }
        elseif(mb_strpos($request['headers'][0], '500')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка Paymaster'
		    );
        }

        if(is_array($json) && isset($json['code'])) {
        	return array(
	        	'success'=>false,
	        	'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
	        );
        }

        return array(
        	'success'=>false,
        	'txt'=>implode('; ', $request['headers'])
        );
	}

	function create_cancel_qr($sum, $return_epay) {
		$receipt_id=$this->f3->get('COOKIE.receipt_id');

		$vars=array(
			"paymentId"=>$return_epay['sbp_order_id'],
			"amount"=>array(
				"value"=>(float)$sum,
				"currency"=>"RUB"
			)
		);
		$options = array(
			'method'=>'POST',
    		'follow_location'=>1,
    		'header'=>array(
    			'Authorization: Bearer '.$this->config['Token'],
    			'Idempotency-Key: '.microtime(true)*10000,
    			'Content-Type: application/json',
    			'Accept: application/json'
    		),
    		'content'=>json_encode($vars)
		);

		$request=$this->web->request('https://paymaster.ru/api/v2/refunds', $options);
		$json=json_decode($request['body'], true);
		if(mb_strpos($request['headers'][0], '200')>0) {
			if(isset($json['code'])) {
				return array(
            		'success'=>false,
            		'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
            	);
			}
            if(mb_strtolower($json['status'])=='rejected' || mb_strtolower($json['status'])=='cancelled') {
            	return array(
            		'success'=>false,
            		'txt'=>'Запрос отклонен'
            	);
            }
            if(mb_strtolower($json['status'])=='pending') {
            	$n=0;
            	while($n<10) {
            		sleep(1);
            		$res=$this->refunds_control(array('sbp_order_id'=>$json['id']));
            		if($res['success']==true) break;
            		elseif(!$res['success'] && $res['show_error']==true) {
		            	return $res;
		            }
		            $n++;
            	}
            }
            $slip="Статус: Успешно\n";
			$slip.="Идентификатор операции\n";
			$slip.=' - в Банке: '.$json['id']."\n";
			return array(
				'success'=>true,
				'txt'=>nl2br($slip),
				'slip'=>nl2br($slip),
				'pan'=>'',
				'transid'=>$return_epay['transid'],
				'authcode'=>'',
			);
        }
        elseif(mb_strpos($request['headers'][0], '401')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка авторизации в Paymaster'
		    );
        }
        elseif(mb_strpos($request['headers'][0], '500')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка Paymaster'
		    );
        }

        if(is_array($json) && isset($json['code'])) {
        	return array(
	        	'success'=>false,
	        	'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
	        );
        }

        return array(
        	'success'=>false,
        	'txt'=>implode('; ', $request['headers'])
        );
	}

	function create_sale_qr($sum) {
		$receipt_id=$this->f3->get('COOKIE.receipt_id');

		$vars=array(
			"merchantId"=>$this->config['merchantId'],
			"invoice"=>array(
				"description"=>"Оплата по чеку ".$receipt_id,
				"orderNo"=>$receipt_id
			),
			"amount"=>array(
				"value"=>(float)$sum,
				"currency"=>"RUB"
			),
			"paymentData"=>array(
				'stickerId'=>$this->config['stickerId']
			),
		);
		$options = array(
			'method'=>'POST',
    		'follow_location'=>1,
    		'header'=>array(
    			'Authorization: Bearer '.$this->config['Token'],
    			'Idempotency-Key: '.microtime(true)*10000,
    			'Content-Type: application/json',
    			'Accept: application/json'
    		),
    		'content'=>json_encode($vars)
		);

		$request=$this->web->request('https://paymaster.ru/api/v2/payments', $options);
		$json=json_decode($request['body'], true);

		if(mb_strpos($request['headers'][0], '200')>0) {
			if(isset($json['code'])) {
				return array(
            		'success'=>false,
            		'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
            	);
			}
			if(mb_strtolower($json['status'])!='confirmation') {
				return array(
					'success'=>false,
					'txt'=>'Ошибка создания платежа'
				);
			}
            return array(
				'success'=>true,
				'qr'=>$this->config['payload'],
				'sbp_order_id'=>$json['id'],
				'receipt_id'=>$receipt_id,
				'show_qr'=>'/receipts/show_qr?receipt_id='.$receipt_id.'&sbp_order_id='.$json['id'].'&epay='.$this->sets['id'].'&sum='.($sum*100).'&url='.urlencode($this->config['payload'])
			);
        }
        elseif(mb_strpos($request['headers'][0], '401')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка авторизации в Paymaster'
		    );
        }
        elseif(mb_strpos($request['headers'][0], '500')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка Paymaster'
		    );
        }

        if(is_array($json) && isset($json['code'])) {
        	return array(
	        	'success'=>false,
	        	'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
	        );
        }

        return array(
        	'success'=>false,
        	'txt'=>implode('; ', $request['headers'])
        );
	}

	function ticket($type, $sum, $return_epay=null, $lines=array()) {
		if($type=='sale') {
			return $this->create_sale_qr($sum);
		}
		return $this->create_cancel_qr($sum, $return_epay);

	}

	function refunds_control($data) {
		$url='https://paymaster.ru/api/v2/refunds/'.$data['sbp_order_id'];
		$options = array(
			'method'=>'GET',
    		'follow_location'=>1,
    		'header'=>array(
    			'Authorization: Bearer '.$this->config['Token'],
    			'Content-Type: application/json',
    			'Accept: application/json'
    		),
		);

		$request=$this->web->request($url, $options);

		$json=json_decode($request['body'], true);

		if(mb_strpos($request['headers'][0], '200')>0) {
			if(isset($json['code'])) {
				return array(
            		'success'=>false,
            		'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
            	);
			}
            if(mb_strtolower($json['status'])=='settled' || mb_strtolower($json['status'])=='success') {
            	$slip="Статус: Успешно\n";
				$slip.="Идентификатор операции\n";
				$slip.=' - в Банке: '.$data['sbp_order_id']."\n";
				return array(
					'success'=>true,
					'txt'=>nl2br($slip),
					'slip'=>nl2br($slip),
					'pan'=>'',
					'transid'=>$data['sbp_order_id'],
					'authcode'=>'',
				);
            }
            if(mb_strtolower($json['status'])=='cancelled') {
            	return array(
					'success'=>false,
					'txt'=>'Статус возврата: Платеж отменен',
					'show_error'=>true
				);
            }
            if(mb_strtolower($json['status'])=='rejected') {
            	return array(
					'success'=>false,
					'txt'=>'Статус возврата: Платеж отклонен',
					'show_error'=>true
				);
            }
            if(mb_strtolower($json['status'])=='confirmation') {
            	return array(
					'success'=>false,
					'txt'=>'Статус возврата: Требуется дополнительное подтверждение',
					'show_error'=>false
				);
            }
            if(mb_strtolower($json['status'])=='pending') {
            	return array(
					'success'=>false,
					'txt'=>'Статус возврата: Платеж выполняется',
					'show_error'=>false
				);
            }
            return array(
				'success'=>false,
				'txt'=>'Статус платежа: Неизвестно',
			);
        }
        elseif(mb_strpos($request['headers'][0], '401')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка авторизации в Paymaster'
		    );
        }
        elseif(mb_strpos($request['headers'][0], '500')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка Paymaster'
		    );
        }

        if(is_array($json) && isset($json['code'])) {
        	return array(
	        	'success'=>false,
	        	'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
	        );
        }

        return array(
        	'success'=>false,
        	'txt'=>implode('; ', $request['headers'])
        );
	}

	function paycontrol_qr($data) {
		$url='https://paymaster.ru/api/v2/payments/'.$data['sbp_order_id'];
		$options = array(
			'method'=>'GET',
    		'follow_location'=>1,
    		'header'=>array(
    			'Authorization: Bearer '.$this->config['Token'],
    			'Content-Type: application/json',
    			'Accept: application/json'
    		),
		);

		$request=$this->web->request($url, $options);

		$json=json_decode($request['body'], true);

		if(mb_strpos($request['headers'][0], '200')>0) {
			if(isset($json['code'])) {
				return array(
            		'success'=>false,
            		'txt'=>isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']
            	);
			}
            if(mb_strtolower($json['status'])=='settled') {
            	$slip="Статус: Успешно\n";
				$slip.="Идентификатор операции\n";
				$slip.=' - в Банке: '.$data['sbp_order_id']."\n";
				return array(
					'success'=>true,
					'txt'=>nl2br($slip),
					'slip'=>nl2br($slip),
					'pan'=>'',
					'transid'=>$data['sbp_order_id'],
					'authcode'=>'',
				);
            }
            if(mb_strtolower($json['status'])=='cancelled') {
            	return array(
					'success'=>false,
					'txt'=>'Статус платежа: Платеж отменен',
					'show_error'=>true
				);
            }
            if(mb_strtolower($json['status'])=='rejected') {
            	return array(
					'success'=>false,
					'txt'=>'Статус платежа: Платеж отклонен',
					'show_error'=>true
				);
            }
            if(mb_strtolower($json['status'])=='confirmation') {
            	return array(
					'success'=>false,
					'txt'=>'Статус платежа: Требуется дополнительное подтверждение',
					'show_error'=>false
				);
            }
            if(mb_strtolower($json['status'])=='pending') {
            	return array(
					'success'=>false,
					'txt'=>'Статус платежа: Платеж выполняется',
					'show_error'=>false
				);
            }
            return array(
				'success'=>false,
				'txt'=>'Статус платежа: Неизвестно',
			);
        }
        elseif(mb_strpos($request['headers'][0], '401')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка авторизации в Paymaster'
		    );
        }
        elseif(mb_strpos($request['headers'][0], '500')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка Paymaster'
		    );
        }

        if(is_array($json) && isset($json['code'])) {
        	return array(
	        	'success'=>false,
	        	'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
	        );
        }

        return array(
        	'success'=>false,
        	'txt'=>implode('; ', $request['headers'])
        );
	}

	function sales($change) {
		if(!$change['time_end'])$change['time_end']=time();
		$vars=array(
  			"merchantId"=>$this->config['merchantId'],
  			"start"=>gmdate('Y-m-d', $change['time_start']).'T'.gmdate('H:i:s', $change['time_start']),
  			"end"=>gmdate('Y-m-d', $change['time_end']).'T'.gmdate('H:i:s', $change['time_end']),
		);
		$options = array(
			'method'=>'GET',
    		'follow_location'=>1,
    		'header'=>array(
    			'Authorization: Bearer '.$this->config['Token'],
    			'Content-Type: application/json',
    			'Accept: application/json'
    		),
		);

		$request=$this->web->request('https://paymaster.ru/api/v2/payments?'.http_build_query($vars), $options);
		$json=json_decode($request['body'], true);
		if(mb_strpos($request['headers'][0], '200')>0) {
			if(isset($json['code'])) {
				return array(
            		'success'=>false,
            		'txt'=>isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']
            	);
			}
            return array(
				'success'=>true,
				'sales'=>$json['items']??array()
			);
        }
        elseif(mb_strpos($request['headers'][0], '401')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка авторизации в Paymaster'
		    );
        }
        elseif(mb_strpos($request['headers'][0], '500')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка Paymaster'
		    );
        }

        if(is_array($json) && isset($json['code'])) {
        	return array(
	        	'success'=>false,
	        	'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
	        );
        }

        return array(
        	'success'=>false,
        	'txt'=>implode('; ', $request['headers'])
        );
	}

	function returns($change) {
		if(!$change['time_end'])$change['time_end']=time();
		$vars=array(
  			"merchantId"=>$this->config['merchantId'],
  			"start"=>gmdate('Y-m-d', $change['time_start']).'T'.gmdate('H:i:s', $change['time_start']),
  			"end"=>gmdate('Y-m-d', $change['time_end']).'T'.gmdate('H:i:s', $change['time_end']),
		);
		$options = array(
			'method'=>'GET',
    		'follow_location'=>1,
    		'header'=>array(
    			'Authorization: Bearer '.$this->config['Token'],
    			'Content-Type: application/json',
    			'Accept: application/json'
    		),
		);

		$request=$this->web->request('https://paymaster.ru/api/v2/refunds?'.http_build_query($vars), $options);
		$json=json_decode($request['body'], true);

		if(mb_strpos($request['headers'][0], '200')>0) {
			if(isset($json['code'])) {
				return array(
            		'success'=>false,
            		'txt'=>isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']
            	);
			}
            return array(
				'success'=>true,
				'returns'=>$json['items']??array()
			);
        }
        elseif(mb_strpos($request['headers'][0], '401')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка авторизации в Paymaster'
		    );
        }
        elseif(mb_strpos($request['headers'][0], '500')>0) {
        	return array(
		    	'success'=>false,
		    	'txt'=>'Ошибка Paymaster'
		    );
        }

        if(is_array($json) && isset($json['code'])) {
        	return array(
	        	'success'=>false,
	        	'txt'=>(isset($this->errors[$json['code']])?$this->errors[$json['code']]:$json['code']).(isset($json['message'])?'<br>'.$json['message']:'')
	        );
        }

        return array(
        	'success'=>false,
        	'txt'=>implode('; ', $request['headers'])
        );
	}

	function report2txt($sales, $returns) {
		$sales_n=0;
		$sales_sum=0;
		$returns_n=0;
		$returns_sum=0;
		foreach($sales as $operation) {
			if(mb_strtolower($operation['status'])=='settled') {
				$sales_n+=1;
				$sales_sum+=$operation['amount']['value'];
			}
		}
		foreach($returns as $operation) {
			if(mb_strtolower($operation['status'])=='success') {
				$returns_n+=1;
				$returns_sum+=$operation['amount']['value'];
			}
		}

		$cheq='Отчет по Пэймастер<br>';
		$cheq.='Продаж - '.$sales_n.'<br>';
		$cheq.='  На сумму - '.number_format($sales_sum, 2, '.', '').'<br>';
		$cheq.='<br>';
		$cheq.='Возвратов - '.$returns_n.'<br>';
		$cheq.='  На сумму - '.number_format($returns_sum, 2, '.', '').'<br>';
		return $cheq.='<br>';
	}

	function z($change) {
		$cheq=$this->sets['title']."<br>Смена успешно закрыта<br>";
		$sales=$this->sales($change);
		if(!$sales['success']) {
			return $sales;
		}

		$returns=$this->returns($change);
		if(!$returns['success']) {
			return $returns;
		}

		$cheq.=$this->report2txt($sales['sales'], $returns['returns']);
		return array(
			'success'=>true,
			'txt'=>nl2br($cheq),
			'slip'=>nl2br($cheq),
			'pan'=>0,
			'transid'=>0,
			'authcode'=>0
		);
	}

	function x($change) {
		$sales=$this->sales($change);
		if(!$sales['success']) {
			return $sales;
		}

		$returns=$this->returns($change);
		if(!$returns['success']) {
			return $returns;
		}

		$cheq.=$this->report2txt($sales['sales'], $returns['returns']);
		return array(
			'success'=>true,
			'txt'=>$cheq,
			'slip'=>$cheq,
			'pan'=>0,
			'transid'=>0,
			'authcode'=>0
		);
	}
}
