<?php
namespace Controllers;
// Контроллер для товаров
class Products extends Controller {

	public function __construct() {
		parent::__construct();
		$this->model=new \Models\Products($this->db, $this->f3);
	}

	function data_matrix($mark) {
		if($this->sets['gs1_symbols']!='') {
        	$mark=str_replace($this->sets['gs1_symbols'], '', $mark);
        }
		$data_matrix=false;
		$add_mark=false;
		$identifiers=array();
		$result='';
		$part21=explode('-', $mark);
        $len=mb_strlen($mark);
        if(($len==8 || $len==13 || $len==14) && ctype_digit($mark)) {
            $result=$mark;
        }
        elseif($len!=8
            && $len!=13
            && $len!=14
            && preg_match("/[A-Za-z0-9\/\\!”%&’'\"()*+-.,:;=<>?]/", $mark)
            && mb_substr($mark, 0, 2)=='01'
            && mb_substr($mark, 16, 2)=='21') {
            $part=explode('', $mark);
            if(count($part)==1) {
                $part=explode('\u001d', $mark);
            }
            //$result=ltrim(mb_substr($part[0], 3, 13), '0');
            $result=mb_substr($part[0], 2, 14);
            $data_matrix=true;
            $add_mark=true;
        }
        elseif($len==29
            && preg_match('/^[0-9a-zA-Z!”%&’\'\/"()*+-.,:;=<>?]+$/' , $mark)
            && ctype_digit(mb_substr($mark, 0, 14))
            && mb_substr($mark, 0, 2)!='01') {
            $result=ltrim(mb_substr($mark, 1, 13), '0');
            $data_matrix=true;
            $add_mark=true;
        }
        elseif($len==21
            && count($part21)==3
            && ctype_alnum($part21[0])
            && ctype_digit($part21[1])
            && ctype_alnum($part21[2])) {
            $result=$mark;
        }
        elseif($len==68 && preg_match('/^[0-9A-Z]+$/' , $mark) && mb_substr($mark, 0, 2)!='01') {
            $result=mb_substr($mark, 8, 23);
            $data_matrix=true;
            $add_mark=true;
        }
        elseif($len==150 && preg_match('/^[0-9A-Z]+$/' , $mark) && mb_substr($mark, 0, 2)!='01') {
            $result=mb_substr($mark, 1, 13);
            $data_matrix=true;
            $add_mark=true;
        }
        else {
        	if(!$this->sets['gs1_symbols'])$this->sets['gs1_symbols']='<GS>';
        	$mark=str_replace('', $this->sets['gs1_symbols'], $mark);
        	$mark=str_replace('\\u001d', $this->sets['gs1_symbols'], $mark);
        	$decoder=new \NGT\Barcode\GS1Decoder\Decoder($this->sets['gs1_symbols']);
			$barcode=$decoder->decode($mark);
			$res=$barcode->toArray();
			if($res['success'] && isset($res['identifiers']['01']['content'])) {
				$data_matrix=true;
				$result=$res['identifiers']['01']['content'];
				$identifiers=$res['identifiers'];
			}
			else {
            	$result=$mark;
            }
        }
		return array(
			'data_matrix'=>$data_matrix,
			'add_mark'=>$add_mark,
			'code'=>$result,
			'identifiers'=>$identifiers,
			'term'=>$mark
		);
	}

	// Поиск по штрих-коду
	function post_search_barcodes() {
		$this->f3->set('GET', $this->f3->get('POST'));
		$this->search_barcodes();
	}

	function search_barcodes() {
		$term=$this->f3->get('GET.product_search');

		// Проверяем принадлежность штрих-кода к набору товаров
		$pr=mb_substr($term, 0, 2);
		$term_len=mb_strlen($term);
		if($pr==$this->f3->get('linesset_pr') && $term_len==13) {
			$lsm=new \Models\Linesset($this->db, $this->f3);
			$linesset=$lsm->select_linesset(array('barcode=?', $term), array('limit'=>1));
			if($linesset) {
				$term=$linesset[0]['txt'];
			}
		}

		$json=json_decode($term, true);
		if(is_array($json)) {
			$res=$this->model->add_lineset($json);
			echo json_encode($res);
			exit();
		}
		$category_id=$this->f3->get('GET.category_id');

		$parent_id=$this->f3->get('GET.parent_id');
		$count=$this->f3->get('GET.coeff');
		
		$not_add=$this->f3->get('GET.not_add');
		$this->f3->set('not_add', $not_add);
		
		$exact_match=$this->f3->get('GET.exact_match');
		$this->f3->set('exact_match', $exact_match);
		
		$in_stock=$this->f3->get('GET.in_stock');
		$this->f3->set('in_stock', $in_stock);
		if($parent_id>0) {
			$res=$this->model->select_product(array('p.date_delete=0 AND p.parent_id=?', $parent_id));
			if($res) {
				$res=array(
					'products'=>$res
				);
			}
		}
		else {
			if(!$term) {
				$this->f3->set('page_data', $this->messages->message('not_enough_data'));
				return;
			}

			$page=$this->f3->get('GET.page');
			if(!$page) $page=1;

			// проверяем дата-матрикс
			$data_matrix=$this->data_matrix($term);
			if($data_matrix['data_matrix']==true) {
				$term=$data_matrix['code'];
				$term_len=mb_strlen($term);
			}
			$s=new \Models\Settings($this->f3, $this->db);
			$sets=$s->get_settings(array('weight_code_pr', 'card_code_pr', 'worker_code_pr'));
			// Проверяем штрих-код на принадлежность к весовому типу
			/*$pr=mb_substr($term, 0, 2);
			if($pr==$sets['weight_code_pr'] && $term_len==13) {
				$barcode=$term;
				$term=mb_substr($barcode, 0, 7);
			}*/

			if(!$not_add) {
				// Проверяем штрих-код на принадлежность к карте клиента
				if($pr==$sets['card_code_pr'] && $term_len==13) {
					$this->f3->reroute('/partners/search_result?q='.$term);
					return;
				}
			}

			if(!$not_add) {
				// Проверяем штрих-код на принадлежность к карте сотрудника
				if($pr==$sets['worker_code_pr'] && $term_len==13) {
					$this->f3->reroute('/receipts/walk?barcode='.$term);
					return;
				}
			}

			$limit=$this->f3->get('lines_of_page');
			$order=$this->f3->get('GET.order');
			if(!$order) {
				$order=false;
			}
			$res=$this->model->search($term, ($page-1)*$limit, $limit, false, $exact_match, $in_stock, $order, false, false, $category_id);
		}
		if($res['weight_barcode']===true) {
			$count=mb_substr($term, 7, 5);
		}
		
		if(empty($res['products'])) {
			if($data_matrix['data_matrix']==true) {
				$this->f3->set('GET.product_search', $data_matrix['code']);
				if($data_matrix['add_mark']) $this->f3->set('GET.marking', 1);
			}
			if(is_numeric($category_id) && $category_id>0) {
				$c=new \Models\Productcategories($this->db, $this->f3);
				$category=$c->select_productcategories(array('id=?', $category_id), array('limit'=>1));
				$this->f3->set('category', $category[0]??array());
			}
			$this->f3->set('page_data', $this->model->page_data('not_found'));
			return;
		}
		elseif(count($res['products'])>1 || $not_add==1) {
			$this->f3->set('pagination', $this->pagination($res['count'], $page));
			$this->f3->set('products', $res['products']);
			$this->f3->set('page_data', $this->model->page_data('search'));
			$this->f3->set('search', $term);
		}
		elseif(count($res['products'])==1) {
			$this->f3->set('GET.parent_id', 0);
			$this->f3->set("POST.receipttype", $this->f3->get('GET.type'));
			if($res['weight_barcode']) {
				if(!$count) $count=0;
				if($res['products'][0]['units']==166) $count/=1000;
			}
			elseif(isset($data_matrix['identifiers']['310'])) {
				if((int)$res['products'][0]['units']==163 || (int)$res['products'][0]['units']==166) {
					$count=(float)$data_matrix['identifiers']['310']['content'];
					if((int)$res['products'][0]['units']==163) $count*=1000;
				}
			}

			$this->f3->set('POST.count', $count??$res['products'][0]['quantity']);
			$this->f3->set("POST.product_id", $res['products'][0]['id']);

			$mark='';
			if($data_matrix['add_mark'] && $data_matrix['data_matrix']) {
				if($res['products'][0]['marking']==0) {
					$this->f3->set('page_data', $this->messages->message('this_not_marking_product'));
					return;
				}
				$this->f3->set("POST.mark", array($data_matrix['term']));
			}
			$c=new \Controllers\Receipts();
			$c->post_add_line();
			return;
		}
	}

	// Поиск товаров для печати ценников
	function pricetags() {
		$term=$this->f3->get('GET.product_search');
		$count=$this->f3->get('GET.coeff');
		
		$not_add=1;
		$this->f3->set('not_add', $not_add);
		
		$exact_match=$this->f3->get('GET.exact_match');
		$this->f3->set('exact_match', $exact_match);
		
		$in_stock=$this->f3->get('GET.in_stock');
		$this->f3->set('in_stock', $in_stock);

		$page=$this->f3->get('GET.page');
		if(!$page) $page=1;

		$limit=$this->f3->get('lines_of_page');
		$order=$this->f3->get('GET.order');
		if(!$order) {
			$order=false;
		}
		$res=$this->model->search($term, ($page-1)*$limit, $limit, false, $exact_match, $in_stock, $order);
		$this->f3->set('pagination', $this->pagination($res['count'], $page));
		$this->f3->set('products', $res['products']);
		$this->f3->set('page_data', $this->model->page_data('pricetags'));
		$this->f3->set('search', $term);
	}

	// Отображение быстрых товаров
	function fast_products() {
		$page=$this->f3->get('GET.page');
		if(!$page) $page=1;
		$limit=$this->f3->get('lines_of_page');
		$res=$this->model->fast_products(($page-1)*$limit, $limit);
		if(empty($res['products'])) {
			$this->f3->set('page_data', $this->messages->message('not_found'));
			return;
		}
		elseif(count($res['products'])>0) {
			$this->f3->set('pagination', $this->pagination($res['count'], $page));
			$this->f3->set('products', $res['products']);
			$this->f3->set('page_data', $this->model->page_data('fast_products'));
		}
	}

	// Показ картинки товара
	function img() {
		$img=$this->f3->get('GET.img');
		if(!$img) {
			$this->f3->set('page_data', $this->messages->message('not_found'));
		}
		else {
			$this->f3->set('img', '//'.$this->api_data['domen'].'/upload/'.$this->api_data['subdomen'].'/300_300/'.$img);
			$this->f3->set('page_data', $this->model->page_data('img'));
		}
	}

	// Узнаем остатки
	function currentstock() {
		$line_id=$this->f3->get('GET.line_id');
		if(!$line_id) {
			$this->f3->set('page_data', $this->model->page_data('search_form'));
		}
		else {
			// Узнаем id продукта
			$l=new \Models\Receiptlines($this->db, $this->f3);
			$line=$l->select_lines(array('id=?', $line_id), array('limit'=>1));
			if(empty($line)) {
				$this->f3->set('page_data', $this->messages->message('not_found'));
			}
			else {
				$prod=$this->model->select_product(array('p.id=?', $line[0]['product_id']), array('limit'=>1));
				if(empty($prod)) {
					$this->f3->set('page_data', $this->messages->message('not_found'));
				}
				else {
					$this->f3->set('product', $prod[0]);
					$this->f3->set('page_data', $this->model->page_data('currentstock'));
				}
			}
		}
	}

	// Состав и КБЖУ
	function compound() {
		$line_id=$this->f3->get('GET.line_id');
		if(!$line_id) {
			$this->f3->set('page_data', $this->messages->message('not_found'));
		}
		else {
			// Узнаем id продукта
			$l=new \Models\Receiptlines($this->db, $this->f3);
			$line=$l->select_lines(array('id=?', $line_id), array('limit'=>1));
			if(empty($line)) {
				$this->f3->set('page_data', $this->messages->message('not_found'));
			}
			else {
				$prod=$this->model->select_product(array('p.id=?', $line[0]['product_id']), array('limit'=>1));
				if(empty($prod)) {
					$this->f3->set('page_data', $this->messages->message('not_found'));
				}
				else {
					$this->f3->set('product', $prod[0]);
					$this->f3->set('page_data', $this->model->page_data('compound'));
				}
			}
		}
	}

	// Список категорий и товаров
	function list($with_stop=true) {
		if(!is_bool($with_stop)) $with_stop=true;
		$c=new \Models\Productcategories($this->db, $this->f3);
		$category_id=$this->f3->get('GET.category_id');
		$parent=array();
		$lines_of_list=$this->sets['lines_of_list'];
		$fast=$this->model->count('fast=1 AND date_delete=0');
		if($fast && !$category_id && $this->sets['cafe_mode']==1) {
			$lines_of_list-=1;
		}
		$this->f3->set('fast', $fast);
		if(!$category_id) {
			$category_id=0;
		}
		else {
			if($this->sets['product_menu']==1) {
				$lines_of_list-=2;
			}
			// Узнаем название родительской категории, если она есть
			$parent=$c->select_productcategories(array('id=? AND date_delete=0', $category_id), array('limit'=>1));
		}
		$this->f3->set('parent', $parent[0]);
		$page=$this->f3->get('GET.page');
		if(!$page) $page=1;
		$this->f3->set('page', $page);

		// Получаем категории
		$kiosk_where='';
		if($this->f3->get('authorization_user.kiosk')==1) {
			$kiosk_where=' AND kiosk_noshow=0';
		}
		$categories=$c->select_productcategories(array('parent_id=? AND show=1 AND date_delete=0'.$kiosk_where, $category_id), array('order'=>'title', 'offset'=>($page-1)*$lines_of_list, 'limit'=>$lines_of_list));
		$this->f3->set('categories', $categories);
		$products=array();
		// сколько всего категорий
		$cat_all=$c->count(array('parent_id=? AND date_delete=0 AND show=1', $category_id));
		// Узнаем надо ли загрузить товары, чтобы добить число позиций на странице до 10
		$cat_count=count($categories);

		$with_stop_where='';
		if(!$with_stop) {
			$with_stop_where=' AND (stop=0 OR stop IS NULL)';
		}
		if($cat_count<$lines_of_list) {
			// Узнаем позицию начала товаров
			// Начало выборки
			$cat_page=intdiv($cat_all, $lines_of_list); // Сколько страниц полностью занято категориями
			$cat_last_page=$cat_all%$lines_of_list; // Сколько категорий на последней странице с категориями

			$prod_page=$page-$cat_page;// Сколько страниц было с товарами
			$prod_first_page=$lines_of_list-$cat_last_page; // Сколько товаров было на первой странице с товарами
			// Считаем начало выборки товаров
			if($prod_page==1) {// Если это первая странице где появляются товары
				$offset=0;
				$limit=$lines_of_list-$cat_last_page;
			}
			else {
				$offset=($prod_page-2)*$lines_of_list+$prod_first_page;
				$limit=$lines_of_list;
			}
			$order='title';
			if($this->sets['stop_list_order']==1) {
				$order='stop, '.$order;
			}
			$products=$this->model->select_product(array('category_id=? AND p.parent_id=0 '.$with_stop_where, $category_id), array('order'=>$order, 'limit'=>$offset.', '.$limit));
		}
		$this->f3->set('products', $products);
		// Узнаем сколько всего товаров
		$prods_all=$this->model->count(array('category_id=? AND parent_id=0 AND date_delete=0'.$with_stop_where, $category_id));
		// Кол-во страниц всего
		$page_all=ceil(($cat_all+$prods_all)/$lines_of_list); //Сколько всего должно быть страниц
		$this->f3->set('page_all', $page_all);

		$receipt_id=$this->f3->get('COOKIE.receipt_id');
		if($receipt_id>0){
			$r=new \Models\Receipts($this->db, $this->f3);
			$r->reset();
			$r->load(array('id=?', $receipt_id), array('limit'=>1));
			$this->f3->set('receipt', $r->cast());
		}

		$this->f3->set('page_data', $this->model->page_data('list'));
	}

	// Страница информации о товаре для клиента
	function barcode() {
		$barcode=$this->f3->get('GET.barcode');

		$s=new \Models\Settings($this->f3, $this->db);
		$sets=$s->get_settings(array('weight_code_pr'));
		// Проверяем штрих-код на принадлежность к весовому типу
		if(mb_substr($barcode, 0, 2)==$sets['weight_code_pr'] && mb_strlen($barcode)==13) {
			$barcode=mb_substr($barcode, 0, 7);
		}

		$product=$this->model->barcode($barcode);
		$product['txt']=$this->messages->message($product['txt'])['txt'];
		if($product['img']) {
			$product['img']='https://'.$this->api_data['domen'].'/upload/'.$this->api_data['subdomen'].'/'.$product['img'];
		}
		echo json_encode($product);
		exit();
	}

	// Форма добавления нового товара
	function form() {
		$inc='add';
		$fr=new \Models\Fr($this->db, $this->f3, 'kkm', false);
		$this->f3->set('sno_org', $fr->sets['sno']);
		$c=new \Models\Productcategories($this->db, $this->f3);
		$this->f3->set('categories', $c->categories_list());
		$title=$this->f3->get('GET.title');
		$product['marking']=$this->f3->get('GET.marking');
		$id=$this->f3->get('GET.id');
		if(is_numeric($title)) {
			$product['barcode']=$title;
			$market_product=$this->model->market_search($title);
			if($market_product) {
				$product['title']=$market_product['title'];
			}
		}
		else {
			$product['title']=$title;
		}
		if($id) {
			$data=$this->model->select_product(array('p.id=? AND p.date_delete=0', $id), array('limit'=>1));
			if($data) {
				$data[0]['barcode']=$this->model->barcodes($id)[0]['barcode'];
				$product=$data[0];
			}
			else {
				$this->f3->set('page_data', $this->messages->message('not_found'));
				return;
			}
			$inc='change';
		}
		$fr=new \Models\Fr($this->db, $this->f3, 'kkm', false);
		//$product['sno']=$fr->sets['sno'];
		$this->f3->set('data', $product);
		$this->f3->set('units', $this->model->units);
		$this->f3->set('marktype', $this->sets['marktype']);
		$this->f3->set('page_data', $this->model->page_data($inc));
	}

	// Добавление нового товара в чек
	function post_form() {
		$post['date_delete']=0;
		$post=$this->f3->get('POST');

		if($post['id'])$action='change';
		else $action='add';

		if(!$this->sets['autonomous'] && $action=='add') {
			$post['id']=-time();
		}

		$post['short_title']=$post['title'];
		$result=$this->model->save_product($post, $action);
		if(!$result['success']) {
			$result['txt']=$this->messages->message($result['txt'])['txt'];
			echo json_encode($result);
			exit();
		}
		if($result['success'] && isset($post['product_id'])) {
			$post['product_id']=$result['id'];
		}

		if(isset($post['product_id'])) {
			if($post['vat_type']>0) {
				$post['price']=round($post['price']/(1+$post['vat']/100), 2);
			}
			$line=array(
				'title'=>$post['title'],
				'id'=>$post['product_id'],
				'price'=>$post['price'],
				'vat'=>$post['vat'],
				'vat_type'=>$post['vat_type'],
				'units_fr'=>$this->model->units[$post['units']]['number'],
				'other_info'=>json_encode(
					$post
				)
			);
			if($post['marking_group']>0) {
				$result['next_step']='/receipts/add_line?product_id='.$post['product_id'].'&count=1';
				$result['txt']=$this->messages->message($result['txt'])['txt'];
				echo json_encode($result);
				exit();
			}
			$receiptlines=new \Models\Receiptlines($this->db, $this->f3);
			$receipt_id=$this->f3->get('COOKIE.receipt_id');
			$result=$receiptlines->add_line($receipt_id, $line, $post['count']);
			if($this->sets['line_merge']) {
				$receiptlines->linesmerge($line['id']);
			}
			if($result['success']) {
				if(!$this->cd) {
					$this->cd=new \Models\Cd($this->db, $this->f3);
				}
				$this->cd->print_line($result['line'], $count);
			}
		}
		$result['txt']=$this->messages->message($result['txt'])['txt'];
		echo json_encode($result);
		exit();
	}

	function directory() {
		$get=$this->f3->get('GET');
		if(!$get['page']) $get['page']=1;
		$limit=$this->f3->get('lines_of_page');
		$offset=($get['page']-1)*$limit;
		$query=array(
			'p.date_delete=0',
			array()
		);
		$res=$this->model->search($get['title']??'', $offset, $limit);
		$products=$res['products'];
		$this->f3->set('data', $products);
		if($products) {
			$this->f3->set('pagination', $this->pagination($res['count'], $get['page']));
		}
		$this->f3->set('page_data', $this->model->page_data('directory'));
	}

	function delete() {
		$id=$this->f3->get('GET.id');
		$res=$this->model->delete($id);
		$res['txt']=$this->messages->message($res['txt'])['txt'];
		echo json_encode($res);
		exit();
	}

	function detail() {
		$id=$this->f3->get('GET.id');
		$page_data=$this->model->page_data('detail');
		$products=$this->model->select_product(array('p.date_delete=0 AND p.id=?', $id), array('limit'=>1));
		if($products) {
			$products[0]['img']=json_decode($products[0]['img'], true);
			$this->f3->set('product', $products[0]);
			$page_data['title']=$products[0]['title'];
		}
		$this->f3->set('page_data', $page_data);
	}

	function stoplist() {
		$page=$this->f3->get('GET.page');
		if(!$page) $page=1;
		$limit=$this->f3->get('lines_of_page');
		//$products=$this->model->select_product(array('p.date_delete=0 AND p.stop=1'), array('offset'=>($page-1)*$limit, 'limit'=>$limit, 'order'=>'title'));
		$exact_match=$this->f3->get('GET.exact_match');
		
		$order=$this->f3->get('GET.order');
		if(!$order) {
			$order=false;
		}
		$products=$this->model->search($this->f3->get('GET.product_search')??'', ($page-1)*$limit, $limit, false, $exact_match, false, $order, false, true);
		$this->f3->set('products', $products['products']);
		if($products['success']) {
			$this->f3->set('pagination', $this->pagination($products['count'], $page));
		}
		$this->f3->set('page_data', $this->model->page_data('stoplist'));
	}

	function addstop() {
		$this->sets['lines_of_list']=$this->f3->get('lines_of_page');
		$this->list(true);
		$this->f3->set('page_data', $this->model->page_data('addstop'));
	}

	function post_changestop() {
		$post=$this->f3->get('POST');
		$product=$this->model->select_product(array('p.id=?', $post['id']), array('limit'=>1));
		if(!$product) {
			$res=array(
				'success'=>false,
				'txt'=>$this->messages->message('not_found')['txt']
			);	
		}
		else {
			if($product[0]['stop']==1) $product[0]['stop']=0;
			else $product[0]['stop']=1;
			$res=$this->model->save_product($product[0], 'change');
			if($res['success']) {
				$api=new \Models\Api($this->f3, $this->api_data['domen'], $this->api_data['pass'], $this->api_data['store_id'], $this->api_data['count']);
				$api->changestop($post);
			}
			$res['txt']=$this->messages->message($res['txt'])['txt'];
		}
		if($res['success']==true) {
			unset($res['close_all_window']);
			$res['close_window']=array('#message', 'form[name="changestop_form"]');
			$res['function']='add_stoplist_success('.$post['id'].')';
		}
		echo json_encode($res);
	}

	function deletestop() {
		$product=$this->model->select_product(array('p.id=?', $this->f3->get('GET.id')), array('limit'=>1));
		if(!$product) {
			$this->f3->set('page_data', $this->messages->message('not_found'));
			return;
		}
		$this->f3->set('product', $product[0]);
		$this->f3->set('page_data', $this->model->page_data('deletestop'));
	}

	function clearstop() {
		$res=$this->model->clearstop();
		if($res['success']) {
			$api=new \Models\Api($this->f3, $this->api_data['domen'], $this->api_data['pass'], $this->api_data['store_id'], $this->api_data['count']);
			$api->clearstop();
		}
		$res['txt']=$this->messages->message($res['txt'])['txt'];
		echo json_encode($res);
	}

	function searchstop() {
		$this->search_barcodes();
		$this->f3->set('page_data', $this->model->page_data('searchstop'));
	}

	function planstock() {
		$get=$this->f3->get('GET');
		$api=new \Models\Api($this->f3, $this->api_data['domen'], $this->api_data['pass'], $this->api_data['store_id'], $this->api_data['count']);
		$res=$api->planstock($get['id']);
		echo json_encode($res);
		exit();
	}
}