<?php
namespace Models;

class esp {
	public $f3, $sets, $config, $logs, $web, $id_pmsr, $token_pmsr;
	public $errors=array(
		1=>'Марка не найдена',
		203=>'Работа в аварийном режиме, аварийная ситуация уже введена и проверки допустимости продажи требуется отключить',
		405=>'Метод не найден',
		400=>'Ошибка в запросе, подробности передаются в теле ответа',
		514=>'ТС ПИоТ не смог получить ответ и от ГИС МТ, и от ЛМ ЧЗ, ТС ПИоТ',
		1000=>'ТС ПИОТ не отвечает'
	);

	function __construct($f3, $sets, $config) {
		$this->f3=$f3;
		$this->sets=$sets;
		$this->config=$config;
		$this->web=\Web::instance();
		$this->id_pmsr=1;
		$this->token_pmsr='token';
		$this->logs=$this->f3->get('logs_model');
	}

	function add_log($request, $response) {
		$txt="Запрос в ТС ПИОТ\n\n".json_encode($request)."\n\n";
		$txt.="Ответ\n\n".json_encode($response);
		$this->logs->save_log($txt);
	}

	function check_mark_result($res, $line) {
		$now=time();
		$success=true;
		if($res['isCheckedOffline']===true) {
			$mark_res=$res['codes'][0];
			if(isset($mark_res['isBlocked']) && $mark_res['isBlocked']==true) {
				return array(
					'success'=>false,
					'check_result'=>-1,
					'error_type'=>'piot',
					'txt'=>'Код идентификации заблокирован по решению ОГВ<br>Марка: '.$this->send_mark.'<br>'.($res['message']??$res['description']),
					'result'=>$mark_res,
					'reqId'=>$res['reqId'],
					'reqTimestamp'=>$res['reqTimestamp'],
					'inst'=>$res['inst']??'',
					'version'=>$res['version']??''
				);
			}
			return array(
				'success'=>true,
				'check_result'=>1,
				'result'=>$mark_res,
				'reqId'=>$res['reqId'],
				'reqTimestamp'=>$res['reqTimestamp'],
				'inst'=>$res['inst']??'',
				'version'=>$res['version']??''
			);
		}
		if($res['code']!=0) {
			$success=false;

			$txt=($this->errors[(int)$res['code']]??($res['description']??'error')).'<br>';
		}
		$mark_res=$res['codes'][0];

		if($mark_res['errorCode']==8 && $mark_res['realizable']===false && $mark_res['grayZone']===true) $mark_res['errorCode']=0;

		if($mark_res['errorCode']>0) {
			$success=false;
			$txt=$this->errors[$mark_res['errorCode']]??$mark_res['message'];
		}
		else {
			if($mark_res['found']===false) {
				$success=false;
				$txt.='Код идентификации не найден в ГИС МТ<br>';
			}

			if($mark_res['utilised']===false) {
				$success=false;
				$txt.='Код маркировки эмитирован, но нет информации о его нанесении<br>';
			}

			if($mark_res['verified']===false) {
				$success=false;
				$txt.='Не пройдена криптографическая проверка кода маркировки<br>';
			}

			if($mark_res['sold']===true) {
				$success=false;
				$txt.='Код идентификации выведен из оборота<br>';
			}

			if($mark_res['isBlocked']===true) {
				$success=false;
				$txt.='Код идентификации заблокирован по решению ОГВ<br>';
			}

			if($mark_res['realizable']===false) {
				if($mark_res['grayZone']!==true || ($line['marking_group']!=3 && $line['marking_group']!=12)) {
					$success=false;
					$txt.='Нет информации о вводе в оборот кода идентификации<br>';
				}
			}

			// #TODO Тут есть косяк с 32-битными системами
			if(isset($mark_res['expireDate']) && strtotime($mark_res['expireDate'])>0 && strtotime($mark_res['expireDate'])<=$now) {
				$success=false;
				$txt.='Товар с истекшим сроком годности.<br>Текущая дата '.date('d.m.Y H:i:s', $now).'. Срок годности до '.date('d.m.Y H:i:s', strtotime($mark_res['expireDate'])).'.<br>';
			}
			if(isset($mark_res['soldUnitCount']) && isset($mark_res['innerUnitCount']) && $line['marking_group']==16) {
				if($mark_res['soldUnitCount']>$mark_res['innerUnitCount']) {
					$success=false;
					$txt.='По данным Честного Знака данной номенклатуры было продано больше('.$mark_res['soldUnitCount'].'), чем содержится в упаковке('.$mark_res['innerUnitCount'].')';
				}
			}
		}

		if(isset($mark_res['smp']) || isset($mark_res['mrp'])) {
			$price=$line['price']+($line['price']*($line['vat']/100))*max(0, $line['vat_type']);
			if(isset($mark_res['smp']) && $mark_res['smp']>0 && $price<$mark_res['smp']) {
				//$success=false;
				//$txt='Продажа ниже минимальной цены. Минимальная цена '.number_format($mark_res['smp']/100, 2, '.', '');
				if($line['vat_type']>0) {
					$mark_res['set_price']=($mark_res['smp']/(100+$line['vat'])*100)/100;
				}
				else {
					$mark_res['set_price']=$mark_res['smp']/100;
				}
			}

			if(isset($mark_res['mrp']) && $mark_res['mrp']>0) {
				//$success=false;
				//$txt='Продажа выше максимальной цены. Максимальная цена '.number_format($mark_res['mrp']/100, 2, '.', '');
				if($line['vat_type']>0) {
					$mark_res['set_price']=($mark_res['mrp']/(100+$line['vat'])*100)/100;
				}
				else {
					$mark_res['set_price']=$mark_res['mrp']/100;
				}
			}
		}

		if($success===false) {
			return array(
				'success'=>false,
				'check_result'=>-1,
				'error_type'=>'piot',
				'txt'=>$txt.'<br>Марка: '.$this->send_mark,
				'result'=>$mark_res,
				'reqId'=>$res['reqId'],
				'reqTimestamp'=>$res['reqTimestamp'],
				'inst'=>$res['inst']??'',
				'version'=>$res['version']??''
			);
		}

		return array(
			'success'=>true,
			'check_result'=>1,
			'result'=>$mark_res,
			'reqId'=>$res['reqId'],
			'reqTimestamp'=>$res['reqTimestamp'],
			'inst'=>$res['inst']??'',
			'version'=>$res['version']??''
		);
	}

	// Запрос проверки марки
	function check_mark_request($mark) {
		$u001d='';
		$mark=str_replace($this->sets['gs1_symbols'], $u001d, $mark);
		$mark=str_replace('\u001d', $u001d, $mark);
		$this->send_mark=htmlentities($mark);
		$mark=base64_encode(trim($mark));
		$vars=array(
			'codes'=>array($mark),
			'client_info'=>array(
				'name'=>$this->f3->get('prog_name'),
				'version'=>$this->f3->get('site_version'),
				'id'=>$this->id_pmsr,
				'token'=>$this->token_pmsr
			)
		);
		$options=array(
			'method'=>'POST',
			'header'=>array(
				'Content-Type: application/json',
			),
			'content'=>json_encode($vars),
			'timeout'=>10
		);

		$url=$this->config['piot_url'].'/api/v1/codes/check';
		$res=$this->web->request($url, $options);
		$json=json_decode($res['body'], true);
		if(isset($json['codesResponse']['codesResponse'][0])) {
			$json=$json['codesResponse']['codesResponse'][0];
			if(!isset($json['code'])) $json['code']=1;
		}
		if(isset($json['code'])) {
			if($json['code']==0) {
				$json['codes'][0]['cis']=htmlentities($json['codes'][0]['cis']);
				$json['codes'][0]['printView']=htmlentities($json['codes'][0]['printView']);
				$json['codes'][0]['message']=htmlentities($json['codes'][0]['message']);
			}

			$res['body']=json_encode($json);

			$vars['codes']=array(htmlentities($mark));
			$options['content']=json_encode($vars);

			$this->add_log($options, $res);
		}
		if(isset($json['status'])) {
			$json['code']=$json['status'];
			$json['description']=$json['error'];
		}

		if(empty($res['headers'])) {
			return array(
				'code'=>1000,
			);
		}

		if(!is_array($json)) {
			return array(
				'code'=>-1,
			);
		}
		return $json;
	}

	function check_mark($line, $mark) {
		$res=$this->check_mark_request($mark);
		if($res['code']<0 || $res['code']==5000 || $res['code']==203) {
			return array(
				'success'=>true,
				'code'=>$res['code'],
				'check_result'=>0,
			);
		}
		if((int)$res['code']!=0) {
			$res['success']=false;
			$res['txt']=$this->errors[$res['code']].'<br>Марка: '.$this->send_mark.'<br>'.($res['message']??$res['description']);
			$res['check_result']=-1;
			return $res;
		}

		$res=$this->check_mark_result($res, $line);
		return $res;
	}
}