<?php
include_once 'config.php';

class IndexBase extends Fly5 {
	protected function _migrate($hid)
	{
		echo "migration ecv2=>ecv3 $hid\n";
		$rows = query("select * from easychange2.bed where hid=:hid", array(
			hid=>$hid,
		));
		foreach($rows as $r) {
			$r[room] = $r[roomno];
			$r[patientname] = $r[patient];
		}
		//print_r($rows);
	}
	protected function buildBedinfos($hid)  {
		/*$rows = query("select * from bedinfo a
			left join bedprop b on 
				a.no = b.bedinfono 
				limit 100");*/
		/*		
		$rows = query("select * from bedinfo 
			where hid='$hid' and ischeckin=1
			order by room, bedno");
		*/
		//빈병상 포함
		$rows = query("select b.*, a.* from bed a
			left outer join bedinfo b
			on a.hid=b.hid and a.room=b.room and a.bedno=b.bedno and b.ischeckin=1
			where a.hid='$hid'
			order by a.room, a.bedno");
		foreach($rows as &$p) {
			$p = $this->buildBedInfo($p);
		}
		return $rows;
	}
	function buildBedInfo($p=null)
	{
		if ($p==null)
			$p = array();
		$fn = "./data/$p[hid]-$p[room]-$p[bedno].json";
		if (
			!$p[patientid] || 
			!is_file($fn)) {
			return $p;
		}
		$a = @file_get_contents($fn);
		
		$a = json_decode($a, true);
		if(!$a) {
			//echo "./data/$p[hid]-$p[room]-$p[bedno].json loading error";
			error_log("./data/$p[hid]-$p[room]-$p[bedno].json loading error");
			return $p;
		}
			
		$skips = array('no', 'hid', 'roomno', 'bedno', 'creationtime', 'updatetime', 'lastalivetime');
		foreach($a as $k=>$v) {
			if (in_array($k, $skips) || $v == null)
				continue;
			$p[$k] = $v;
		}
		
		$fds = query("select * from forceprop where 
			hid=:hid and room=:room and bedno=:bedno", $p);
		foreach($fds as $fd) {
			$p[$fd[k]] = $fd[v];
			$p[prop_forced] = 1;
		}
		return $p;
	}
	
	function putBedProp($a){
		query("insert into forceprop
				(hid, room, bedno, k, v)
			values 
				(:hid, :room, :bedno, :key, :val)
			on duplicate key update
				v=:val;
			insert into forcebed
				(hid, room, bedno, enabled)
			values
				(:hid, :room, :bedno, 1)
			on duplicate key update
				enabled=1;", $a);
		//query("insert into 
	}
};
class Index extends IndexBase {
	function locate_patient($a)
	{
		$a[auto_located] = 0;
		// ocs데이터 -> 침대 배치
		try{
			query("insert into bedinfo 
					(hid, room, bedno, ocsbedno, patientname, auto_located, patientid) 
				values
					(:hid, :room, :bedno, :bedno, :patientname, :auto_located, :patientid)
				on duplicate key update
					patientname=:patientname,
					room=:room,
					bedno=:bedno,
					ocsbedno=:bedno, 
					patientid=:patientid,
					lastalivetime=NOW(),
					ischeckin=1,
					auto_located=:auto_located", $a);
		}catch(Exception $e){
			echo $e;
			print_r($a);
			file_put_contents("./tmp/error-".date("Ymj Hms").'.txt', json_encode($a));
			return;
		}
		
		file_put_contents("./data/$a[hid]-$a[room]-$a[bedno].json", json_encode2($a));
		// 갱신 관련 정보 처리 
		// 실제 내용이 바뀐 경우만 updatetime을 갱신
		// 네임택 쪽에서는 bedinfo updatetime 과, 네임택을 갱신했던 마지막 시간을 비교해서 네임택 갱신을 실시한다
		
		$bedinfo = $this->buildBedInfo($a);
		$bedinfo[lastalivetime] = null;
		$bedinfo[lastmd5] = null;
		$bedinfo[md5] = null;
		$bedinfo[updatetime] = null;
		$md5 = md5(json_encode($bedinfo));
		query("update bedinfo set lastmd5=md5, md5='$md5' where no=:no;
			update bedinfo set updatetime=NOW() 
			where no=:no and md5<>lastmd5;
		", $bedinfo);
		//query("update bedinfo set md5='$md5' where no=:no", $bedinfo);
		//query("update bedinfo set updatetime=NOW() 
			//where no=:no and md5<>lastmd5", $bedinfo);
			
		/*
		$rows = query("select * from bedinfo where hid=:hid and room=:room and bedno=:bedno and ischeckin=1", $a);
		$bi = $rows[0];
		$skips = array('no', 'hid', 'roomno', 'bedno', 'patientname', 'creationtime');
		foreach($a as $k => $v) {
			if (in_array($k, $skips) || $v == null)
				continue;
			$p = array(
				bedinfono=>$bi[no],
				k=>$k,
				v=>$v,
			);
			//ll($p);
			query("insert into bedprop
					(bedinfono, `k`, `v`)
				values
					(:bedinfono, :k, :v)
				on duplicate key update
					`v`=:v", $p);
		}
		*/
		
	}
	
	function autolocate_patient($p)
	{
		query("delete from bedinfo where hid=:hid and patientid=:patientid", $p); // 자리이동일 경우가 있으므로, 동일환자는 우선 제거
		$rows = query("select * from bedinfo where room=:room and ischeckin=1 
			order by bedno
			", $p);
		$n = 1;
		while ($n < 1000) {
			$t = array_filter($rows, function($p){
				//print_r($p);
				return $p[bedno] == $n;
			});
			if(count($t) == 0)
				break;
			$n++;
		}
		//$n += 1000;
		$p[bedno] = $n;
		$p[auto_located] = 1;
		$this->locate_patient($p);
		ll('autolocated', $p, 
			query("select * from bedinfo where room=:room and ischeckin=1 order by bedno", $p)
		);
	}
	
	function put_patients()
	{
		/*
			환자 입력 전략
			* bedno 가 null인 경우는 없음 (db에서 불가)
			hid-room-bedno-checkin 이 고유키
			hid-room-bedno-null 은 존재 가능 (같은 room-bedno 에 checkout 된 환자는 중복 존자 가능)
			
			
			1. timeout 에 걸린 환자를 checkout
			2. bedno 가 있는 환자를 모두 input
			3. bedno 없는 환자를 임의 배치
			
		*/
		// 1. timeout 환자 청소
		
		$s = file_get_contents('php://input');
		$a = json_decode($s, true);
		//new PDOConfig('127.0.0.1', 'uis', 'root', 'dpadhel@tjqj');
		if (!$a) {
			file_put_contents(tempnam('./tmp/', "error_$_SERVER[REMOTE_ADDR]_"), $s);
		} else {
			file_put_contents("./tmp/patient_dump_$a[hid].txt", $s);
		}

		query("update bedinfo set ischeckin=null where hid=:hid and lastalivetime < DATE_ADD(now(), interval -30 minute)", $a);
		
		//test환자만들기
		if($_REQUEST[debug]){
			foreach($a[patients] as &$p) {
				if(rand(0, 10) < 1) {
					print_r($p);
					//print_r(query("select * from bedinfo where room=:room and bedno=:bedno and ischeckin=1", $p));
					// query("delete from bedinfo where room=:room and bedno=:bedno and ischeckin=1", $p);
					$p[bedno] = null;
				}
			}
		}
		
		// 환자 데이터 normalize
		foreach($a[patients] as &$p) {
			//if ($p[room]=='513')	print_r($p);
			$p[patientname] = $p[name];
			$p[patientid] = $p[chartid];
		}
		
		// 환자 침상에 넣기
		$assigned = array_filter($a[patients], function($p){
			return $p[bedno]==true;
		});
		foreach($assigned as &$p) {
			$this->locate_patient($p);
		}
		
		// bedno 없는 환자 자동 배치
		$unassigned = array_filter($a[patients], function($a){
			return $a[bedno] == false;
		});
		ll('unassigned', $unassigned);
		foreach($unassigned as $p) {
			$this->autolocate_patient($p);
		}
		
		echo "ok";
	}
	
	function buildBedDefs($hid)
	{
		$rows = query("select * from beddef where isnull(hid) or hid='$hid' and disabled=0 order by rank");
		
		//print_r($rows); die();
		return $rows;
	}
	function editor(&$view)
	{
		$view = 'editor.pug';
		
		$hid = $_REQUEST[hid];//'lm06';
		if(!$hid)
			die('hid is needed');
		return array(
			hospitalinfo=>query("select * from hospital where hid='$hid'")[0],
			beddef=>$this->buildBedDefs($hid),
			beds=>$this->buildBedinfos($hid),
			hospital=>query("select * from hospital where hid='$hid'")[0],
		);
	}
		
	function execute(&$view, $path, $args){
		$a = $_REQUEST;
		switch($path) {
		case 'index':
			$view = 'index.pug';
			if ($a[username]) {
				setCookie("username", $a[username], 0x7fffffff, '/');
				setCookie("hid", "IM39", 0x7fffffff, '/');
			}			
			header('location: Home/welcome');
			die();
			break;
		case 'api/patient/put':
			$this->put_patients();
			break;
		case 'api/migrate':
			$this->_migrate($hid);
			break;			
		case 'api/bed/prop/put':
			$this->putBedProp($_REQUEST);
			die('ok');
			break;
		case 'api/diet/fetch-meals':
			$this->fetchMeals();
		default:
			$view=$path.".pug";
		}
	}
	function buildBeds()
	{
		$a = $_REQUEST;
		if(!$a[hid])
			die('hid is needed');
		
		
		query("delete from bed where hid=:hid", $a);
		$rows = query("select * from room where hid=:hid", $a);
		$db = opendb();
		$rs  = $db->pdo->prepare("insert into 
					bed (hid, room, bedno)					
					values (?, ?, ?)");
		foreach($rows as $room) {
			for($i = 1; $i <= $room[bedcount]; $i++) {
				$room[bedno] = $i;
				$rs->execute(array($room[hid], $room[roomname], $i));
			}
		}
		print_r(query("select * from bed where hid=:hid", $a));
	}
}

