<?php
require_once(SITE_LOGICS . 'register/model.php');

class LogicRegister extends RegisterModelClass {

	/*-------------------------------------------------------------------------
	* @ メンバ変数
	-------------------------------------------------------------------------*/
	private $htmlStr = NO_STRING;	// 表示用HTML文字列

	/**
	 * 
	 * @var PotentialDuplicateAccountChecker
	 */
	private $pot;
	
	/**
	 * 
	 * @var DuplicateAccount
	 */
	private $registeredAccount;
	
	/*-------------------------------------------------------------------------
	* @function_name: ロジックのコンストラクタ
	* @parameter	: なし
	* @return		: なし
	-------------------------------------------------------------------------*/
	function __construct() {
		parent::__construct();
		
		$this->pot = new PotentialDuplicateAccountChecker();
	}

	/*-------------------------------------------------------------------------
	* @function_name: ロジック（各クラス共通）
	* @parameter	: なし
	* @return		: TRUE:ロジック成功、FALSE:ロジック失敗
	-------------------------------------------------------------------------*/
	function logic() {

		try {

			// 初期データ処理
			$this -> init();

			// ロジック実行
			$this -> biz();

		} catch (Exception $e) {
			throw $e;
		}
	}

	/*-------------------------------------------------------------------------
	* @function_name: ロジックの実行
	* @parameter	: なし
	* @return		: なし
	-------------------------------------------------------------------------*/
	private function biz() {

		if($this -> getType()	== TYPE_COMPLETE) {	// 完了
			$this -> regist();
		}
	}

	/*-------------------------------------------------------------------------
	* @function_name: ロジックの実行
	* @parameter	: なし
	* @return		: なし
	-------------------------------------------------------------------------*/
	private function regist() {

		// 口座番号の作成
		$account = $this -> createAccount();

		// UIDの作成
		$uId = $this -> createUId();

		// データの登録
		if($this -> insert($uId, $account)) {	// 登録が成功した場合
			$acc = $this -> getAccountCommon($account)[NO_COUNT];
			$this -> send();
			$this -> setRegisteredAccount($acc);
			// temporary disabled as it cause 500 connection timeout
			// $this -> process($acc);
			// temporary disabled as it cause 500 connection timeout
		}
	}

	/*-------------------------------------------------------------------------
	* @function_name: 情報の登録
	* @parameter	: UID，口座番号
	* @return		: なし
	-------------------------------------------------------------------------*/
	private function insert($uId, $account) {

		// 変数宣言部
		$rtn	= true;
		$params = array();
		$crmId	= NO_STRING;

		// パラメータの設定
		$params[]	= $uId;							// UID
		$params[]	= $this -> getEMail();			// ログインID
		$params[]	= password_hash(
		    $this -> getPassword().VAL_STR_AUTH_HASH_SECRET_KEY, 
		    PASSWORD_BCRYPT, 
		    array('cost' => 13)
		);		// ログインパスワード

		// ログインデータの登録
		$rtn = $this -> accessModify('INSERT_LOGIN', $params);

		// データが正常更新されなければ返却
		if(!$rtn) {
			return $rtn;
		}

		// パラメータの設定（ユーザテーブル）
		$params		= $this -> createParams($uId, $account);


		// ユーザ情報登録の前にCRM IDを取得する
		$crmId		= $this -> crmInsertRecords($params);
		$params[VAL_INT_21]	= $crmId;

		$rtn		= $this -> accessModify('INSERT_USER', $params);

		$this -> accessModify('INSERT_2FA_ENABLE', array($account), false);
		$this -> accessModify('INSERT_2FA_CODE', array($account), false);

		if($this -> getAccountType() == VAR_CORP) {

			// データが正常更新されなければ返却
			if(!$rtn) {
				return $rtn;
			}

			// パラメータの設定（法人テーブル）
			$params		= $this -> createParamsCorporate();
			$rtn		= $this -> accessModify('INSERT_CORPORATION', $params);
		}

		// ログインデータの登録
		return $rtn;
	}

	/*-------------------------------------------------------------------------
	* @function_name: 申請メールの送信
	* @parameter	: なし
	* @return		: なし
	-------------------------------------------------------------------------*/
	private function send() {
		$this -> sendRegistMailCommon($this -> getUserAccount());
	}

	/*-------------------------------------------------------------------------
	* @function_name: ページ出力文字列取得関数
	* @parameter	: なし
	* @return		: HTML文字列
	-------------------------------------------------------------------------*/
	function getDisplay() {
		return $this -> htmlStr;
	}
	
	/**
	 * anton
	 * 
	 * @param unknown $registration
	 */
	private function process($registration){
		$startTime = microtime(true);
		
		$dups = [];
		
		$accounts = $this -> accounts();
		
		foreach($accounts as $k => $o){
		    $this->pot->setAccounts($this -> registeredAccount, $o);
		    $this->pot->validateRegisteredAccount(function($threshold) use($k, $accounts, &$dups) {
		        $accounts[$k]->threshold = $threshold;
		        $dups[] = $accounts[$k];
		    });
		}
		
		if($this->registeredAccount->potentialDuplicate){
		    $dupjson = json_encode($dups);
		    $dupjson = str_replace("\\t", "\\\\t", $dupjson);
		    
		    $this -> accessModify('UPDATE_USER_THRESHOLD', [$this->registeredAccount->threshold,
					$dupjson,
					$this -> registeredAccount -> accountNo], false);
		}
		
		$endTime = microtime(true);
		$seconds = $endTime - $startTime;
		
		return $seconds;
	}
	
	
	/**
	 * 
	 * @return DuplicateAccount[]
	 */
	private function accounts(){
	    $det = $this -> accessSelect('LIST_USERS_BASIC_DETAILS', ['AND user_account != (\')'
	        .$this -> registeredAccount -> accountNo.'(\')']);
	    $acc = [];
	    
	    if($this -> isLoopData($det)){
	        foreach($det as $v){
	            $dupAcc = new DuplicateAccount();
	            $this->toAccount($dupAcc, $v);
	            $acc[] = $dupAcc;
	        }
	    }
	    
	    return $acc;
	}
	
	private function setRegisteredAccount(Array $acc){
	    $this->registeredAccount = new DuplicateAccount();
	    $this->registeredAccount->accountNo     = $acc["user_account"];
	    $this->registeredAccount->firstName     = $acc["first_name"];
	    $this->registeredAccount->lastName      = $acc["last_name"];
	    $this->registeredAccount->emailAddress  = explode('@', $acc["mail"])[0];
	    $this->registeredAccount->dateOfBirth   = $acc["birth"];
	    $this->registeredAccount->homeAddress   = $acc["address"];
	    $this->registeredAccount->ipAddress     = $acc["create_ip_address"];
	    $this->registeredAccount->status        = $acc["status"];
	    $this->registeredAccount->createTime    = $acc["create_time"];
	    $this->registeredAccount->country       = $acc["country"];
	}
	
	private function toAccount(DuplicateAccount &$acc, Array $arr) : void {
	    $acc->accountNo     = $arr["user_account"];
	    $acc->firstName     = $arr["first_name"];
	    $acc->lastName      = $arr["last_name"];
	    $acc->emailAddress  = $arr["mail"];
	    $acc->dateOfBirth   = $arr["birth"];
	    $acc->homeAddress   = $arr["address"];
	    $acc->ipAddress     = $arr["create_ip_address"];
	    $acc->status        = $arr["status"];
	    $acc->createTime    = $arr["create_time_string"];
	    $acc->country       = $arr["country"];
	}

}
?>