<?php
namespace Models;

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

	public $pg=array(
		1=>array('title'=>'Предметы одежды, бельё постельное, столовое, туалетное и кухонное', 'pg'=>1),
		2=>array('title'=>'Обувные товары', 'pg'=>2),
		3=>array('title'=>'Табачная продукция', 'pg'=>3),
		4=>array('title'=>'Духи и туалетная вода', 'pg'=>4),
		5=>array('title'=>'Шины и покрышки пневматические резиновые новые', 'pg'=>5),
		6=>array('title'=>'Фотокамеры (кроме кинокамер), фотовспышки и лампы-вспышки', 'pg'=>6),
		7=>array('title'=>'Медицинские изделия', 'pg'=>10),
		8=>array('title'=>'Молочная продукция', 'pg'=>8),
		9=>array('title'=>'Велосипеды и велосипедные рамы', 'pg'=>9),
		10=>array('title'=>'Медицинские изделия', 'pg'=>10),
		//11=>array('title'=>'Алкоголь', 'pg'=>11),
		11=>array('title'=>'Товары из натурального меха', 'pg'=>14),
		12=>array('title'=>'Альтернативная табачная продукция', 'pg'=>12),
		13=>array('title'=>'Упакованная вода', 'pg'=>13),
		14=>array('title'=>'Соковая продукция и безалкогольные напитки', 'pg'=>23),
		15=>array('title'=>'Пиво, напитки, изготавливаемые на основе пива, слабоалкогольные напитки', 'pg'=>15),
		16=>array('title'=>'Пиво, напитки, изготавливаемые на основе пива, слабоалкогольные напитки', 'pg'=>15),
		17=>array('title'=>'Фармацевтическое сырьё, лекарственные средства', 'pg'=>38),
		18=>array('title'=>'Специализированная пищевая продукция и БАД к пище', 'pg'=>17),
		19=>array('title'=>'Антисептики и дезинфицирующие средства', 'pg'=>19),
		20=>array('title'=>'Морепродукты', 'pg'=>21),
		21=>array('title'=>'Корма для животных', 'pg'=>20),
		22=>array('title'=>'Безалкогольное пиво', 'pg'=>22),
		23=>array('title'=>'Растительные масла', 'pg'=>33),
		24=>array('title'=>'Ветеринарные препараты', 'pg'=>26),
		25=>array('title'=>'Медицинские изделия', 'pg'=>10),
		26=>array('title'=>'Консервированная продукция', 'pg'=>32),
		27=>array('title'=>'Бакалейная продукция', 'pg'=>37),
		28=>array('title'=>'Косметика, бытовая химия и товары личной гигиены', 'pg'=>35),
		29=>array('title'=>'Моторные масла', 'pg'=>43),
		30=>array('title'=>'Никотиносодержащая продукция', 'pg'=>16),
		31=>array('title'=>'Титановая металлопродукция', 'pg'=>31),
		32=>array('title'=>'Мясные изделия', 'pg'=>25),
		33=>array('title'=>'Игры и игрушки для детей', 'pg'=>27),
		34=>array('title'=>'Оптоволокно и оптоволоконная продукция', 'pg'=>34),
		35=>array('title'=>'Радиоэлектронная продукция', 'pg'=>28),
		36=>array('title'=>'Печатная продукция', 'pg'=>36),
		39=>array('title'=>'Строительные материалы', 'pg'=>39),
		40=>array('title'=>'Пиротехника и огнетушащее оборудование', 'pg'=>40),
		41=>array('title'=>'Отопительные приборы', 'pg'=>41),
		42=>array('title'=>'Кабельно-проводниковая продукция', 'pg'=>42),
		44=>array('title'=>'Полимерные трубы', 'pg'=>44),
		45=>array('title'=>'Сладости и кондитерские изделия', 'pg'=>45),
		48=>array('title'=>'Автозапчасти и комплектующие транспортных средств', 'pg'=>48),
		49=>array('title'=>'Натуральный мех', 'pg'=>49),
		50=>array('title'=>'Радиоэлектронная продукция. Электронные системы доставки никотина', 'pg'=>50),
		51=>array('title'=>'Радиоэлектронная продукция. Ноутбуки и смартфоны', 'pg'=>51),
		52=>array('title'=>'Полуфабрикаты и замороженные продукты', 'pg'=>52),
		53=>array('title'=>'Удобрения в потребительской упаковке', 'pg'=>53),
		54=>array('title'=>'Товары для дома и интерьера', 'pg'=>54),
	);

	function __construct($f3, $sets, $config) {
		$this->f3=$f3;
		$this->sets=$sets;
		$this->config=$config;
		$this->web=\Web::instance();
		$this->id_pmsr="6e49c916-3dcc-47ba-a86f-cd8208bbbb27";
		//$this->token_pmsr="9b15f05a-11d9-4fd7-9025-daa5d867a35d";
		$this->token_pmsr=md5(1);
		$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, 'info');
	}

	function check_mark_result($res, $line) {
		$now=time();
		$success=true;
		$txt='';
		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['errorCode']>0) {
			$success=false;
			$txt.=($this->errors[(int)$res['errorCode']]??$res['errorDescription']).'<br>'.($res['errorDescription']??'').'<br>';
		}
		if(!isset($res['code']) || $res['code']!=0) {
			$success=false;
			$txt.=($this->errors[(int)$res['code']]??($res['description']??'Отсутствует описание ошибки для поля code = '.($res['code']??'отсутствует'))).'<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['mrp']) && $mark_res['mrp']>0) {
			if($this->pg[$line['marking_group']]['pg']==16) {
				$price=$line['price']+($line['price']*($line['vat']/100))*max(0, $line['vat_type']);
				if($price<$mark_res['mrp']/100) {
					$success=false;
					$txt.='Цена ('.$price.') меньше минимальной ('.($mark_res['mrp']/100).')';
				}
			}
			else {
				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(isset($mark_res['smp']) && $mark_res['smp']>0) {
			$smp_count=1;
			if(isset($mark_res['packageType']) && mb_strtoupper($mark_res['packageType'])=='GROUP' && isset($mark_res['packageQuantity']) && $mark_res['packageQuantity']>0) {
				$smp_count=$mark_res['packageQuantity'];
			}
			$mark_res['smp']*=$smp_count;
			if(isset($mark_res['set_price'])) {
				$price=$mark_res['set_price']*100;
			}
			else {
				$price=$line['price']+($line['price']*($line['vat']/100))*max(0, $line['vat_type']);
			}
			if($price<$mark_res['smp']) {
				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']) && isset($mark_res['smp']) && $mark_res['mrp']<$mark_res['smp']) {
			$success=false;
			$txt.='Ошибка данных Честного Знака. Максимальная цена ('.($mark_res['mrp']/100).') меньше минимальной ('.($mark_res['smp']/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;
	}
}