<?php
	define( "CC_STATUS_SUCCESSFUL"				,0x00);
	define( "CC_STATUS_UNAVAILABLE_ERROR"		,0x01);
	define( "CC_STATUS_UNAVAILABLE_ERROR2"		,0x02);
	define( "CC_STATUS_CANCELED"				,0x03);
	define( "CC_STATUS_DECLINED"				,0x04);
	define( "CC_STATUS_FAILED"					,0xFF);

	require_once( $GLOBALS["site_root"]."/includes/models/TemplateMail.inc.php" );
	require_once( $GLOBALS["site_root"]."/includes/models/Constants.inc.php" );
	require_once( $GLOBALS["site_root"]."/includes/models/User.inc.php" );
	require_once( $GLOBALS["site_root"]."/includes/models/TaskManager.inc.php" );

	class CreditCardModel {
		protected $bank_model = false;
		protected $sBankName = "";
		protected $sBackUrlFormatString = "";

		protected function createBankModel() {
			if ($this->bank_model) return;
			switch ($this->sBankName) {
			case "otp":
				require_once( $GLOBALS["site_root"]."/includes/models/Otp.inc.php" );
				$this->bank_model = new OtpModel();
				break;
			}
		}

		public function __construct( $bank_name = "otp" ) {
			$this->sBankName = $bank_name;

			$this->sBackUrlFormatString = sprintf( "http://%s%s/otp-tranzakcio-ellenorzes/?tran_id=%%s",
				$_SERVER["SERVER_NAME"],
				$GLOBALS["site_www"] );
		}

		public function updateBankTransactionId( $cc_tran_id , $bank_tran_id ) {
			$upd = array();
			$upd["bank_transaction_id"]=sprintf( "'%s'" , FNTH_db_addslashes( $bank_tran_id ) );
			$query = FNTH_db_generate_update_query( "cc_transactions" , $upd , sprintf( "cc_transaction_id=%d" , $cc_tran_id ) );
			FNTH_db_free_result( FNTH_db_query( $query ) );
		}

		public function setBackUrlFormatString( $v ) { $this->sBackUrlFormatString = $v; }

		public function startTransaction( $user_id , $price , $currency , $comment , $extra_params = array() ) {
			// elokeszitjuk az objektumot
			$this->createBankModel();
			if (!$this->bank_model) return;
			// visszapasszoljuk, ha callbackelni kell
			$this->bank_model->setCreditCardModelObject( $this );
			if (method_exists( $this->bank_model , "setBackUrlFormatString" ))
				$this->bank_model->setBackUrlFormatString( $this->sBackUrlFormatString );

			// insert global transaction transaction
			$ins = array();
			$ins["user_id"]=sprintf( "%d" , $user_id );
			$ins["bankname"]=sprintf( "'%s'" , FNTH_db_addslashes( $this->sBankName ) );
			$ins["amount"]=sprintf( "%f" , $price );
			$ins["currency"]=sprintf( "'%s'" , FNTH_db_addslashes( $currency ) );
			if (isset( $extra_params["prolong_days"] ))
				$ins["prolong_days"]=$extra_params["prolong_days"];

			$query = FNTH_db_generate_insert_query( "cc_transactions" , $ins );
			FNTH_db_free_result( FNTH_db_query( $query ) );
			$query = sprintf( "select currval('cc_transactions_cc_transaction_id_seq') as num" );
			$cc_tran_id = FNTH_db_get_field( $query , "num" );

			// elinditjuk a bank-specko tranzakciot
			$bank_tran_id = $this->bank_model->startNewTransaction( $cc_tran_id , $price , $currency , $comment );

			// elkepzelheto, hogy timeout eseten nem adja vissza
			if ($bank_tran_id)
				$this->updateBankTransactionId( $cc_tran_id , $bank_tran_id );
			return $cc_tran_id;
		}

		public function isTransactionExists( $cc_tran_id ) {
			return FNTH_db_get_field( sprintf( "select count(*) as num from cc_transactions where cc_transaction_id=%d" , $cc_tran_id ) , "num" );
		}

		public function isTransactionClosed( $cc_tran_id ) {
			$query = sprintf( "select is_closed from cc_transactions where cc_transaction_id=%d" , $cc_tran_id );
			return (FNTH_db_get_field( $query , "is_closed" )=="t");
		}

		public function isUserTransaction( $user_id , $cc_tran_id ) {
			$query = sprintf( "select count(*) as num from cc_transactions where user_id=%d and cc_transaction_id=%d" , $user_id , $cc_tran_id );
			return (FNTH_db_get_field( $query , "num" ) > 0);
		}

		protected function prepareTransaction( $tran ) {
			if (isset( $tran["paid_tstamp"] ))
				$tran["paid_tstamp_text"]=fo3_format_datetime_to_screen( $tran["paid_tstamp"] );
			return $tran;
		}

		public function getTransactionFromTransactionId( $cc_tran_id ) {
			$query = sprintf( "select * from cc_transactions where cc_transaction_id=%d" , $cc_tran_id );
			$retval = FNTH_db_get_row( $query );
			return $this->prepareTransaction( $retval );
		}

		public function finishTransaction( $cc_tran_id ) {
			require_once( $GLOBALS["site_root"] . "/includes/models/Member.inc.php" );
			require_once( $GLOBALS["site_root"] . "/includes/models/UserLog.inc.php" );

			if ($this->isTransactionClosed( $cc_tran_id )) return;
			$tran = $this->getTransactionFromTransactionId( $cc_tran_id );
			$this->bank_model = false;	
			switch ($tran["bankname"]) {
			case "otp":
				require_once( $GLOBALS["site_root"]."/includes/models/Otp.inc.php" );
				$this->bank_model = new OtpModel();
				break;
			}
			if (!$this->bank_model) return;
			FNTHLog::logMessage( sprintf( "finishing transaction #%d" , $tran["bank_transaction_id"] ) );
			$status = $this->bank_model->finishTransaction( $tran["bank_transaction_id"] );
			FNTHLog::logMessage( sprintf( "returning status <%s>" , $status ) );
			$upd = array();
			switch ($status) {
			case CC_STATUS_SUCCESSFUL:
				$upd["paid_tstamp"]="now()";
				$upd["is_closed"]="true";
				break;
			case CC_STATUS_CANCELED:
				$upd["cancel_tstamp"]="now()";
				$upd["is_closed"]="true";
				break;
			default:
				// valami hiba es megsem sikerul lekerdezni
				return $status;
			}
			$query = FNTH_db_generate_update_query( "cc_transactions" , $upd , sprintf( "cc_transaction_id=%d",$cc_tran_id ) );
			FNTH_db_free_result( FNTH_db_query( $query ) );
			// ha ide eljutottunk
			if ($status!=CC_STATUS_SUCCESSFUL) return $status;
			// akkor mar csak a nyujtas kell
			$mm = new MemberModel();
			$member = $mm->getMemberFromUserId( $tran["user_id"] );
			if (!$member) return CC_STATUS_FAILED;
			$mm->prolongMember( $member["member_id"] , $tran["prolong_days"] , PM_CREDIT_CARD ,
				array(
					"transaction_id" => $cc_tran_id,
					"amount" => $tran["amount"],
					"currency" => $tran["currency"] ) );

			// log message
			$ulm = new UserLogModel();
			$ulm->logMemberActivity( USER_LOG_MONETARY | USER_MONETARY_CREDITCARD , sprintf( "bankkártyával fizetett (#%d - %d %s)",
				$cc_tran_id , $tran["amount"] , $tran["currency"] ),$member["member_id"] );

			// meg kikuldeni az emaileket
			$um = new UserModel();
			$user = $um->getUserFromUserId( $tran["user_id"] );
			// 1. user
			$mail = new TemplateMailModel( "sys_creditcard_transaction_successful" );
			$cm = new ConstantsModel( $mail );
			$cm->addSystemParametersToTemplate();
			$cm->addUserConstantsToTemplate( $tran["user_id"] , "user" , $user );
			$cm->addMemberConstantsToTemplate( $member["member_id"] );
			$cm->addCreditcardConstantsToTemplate( $cc_tran_id );
			$mail->sendMail( $user["email"] );
			
			// 2. admin
			$mail = new TemplateMailModel( "sys_admin_creditcard_transaction_successful" );
			$cm = new ConstantsModel( $mail );
			$cm->addSystemParametersToTemplate();
			$cm->addUserConstantsToTemplate( $tran["user_id"] , "user" , $user );
			$cm->addMemberConstantsToTemplate( $member["member_id"] );
			$cm->addCreditcardConstantsToTemplate( $cc_tran_id );
			$mail->sendMail( $GLOBALS["fo3_admin_email"] );

			// create status send task
			$tm = new TaskManagerModel();
			$tm->createStatusSendTask( array( $member["member_id"] ) );

			return $status;
		}

		public function getLastUnclosedUserTransaction( $user_id ) {
			$query = sprintf( "select cc_transaction_id from cc_transactions where user_id=%d and not is_closed order by ctstamp desc limit 1" , $user_id );
			return FNTH_db_get_field( $query , "cc_transaction_id" );
		}
		
		public function getUnfinishedTransactionIds( $offset = 0 , $limit = 10 ) {
			$query = sprintf( "select cc_transaction_id from cc_transactions where paid_tstamp is null and cancel_tstamp is null order by cc_transaction_id offset %d limit %d" , $offset , $limit );
			return FNTH_db_get_column( $query , "cc_transaction_id" );
		}

		public function getNumberOfUnfinishedTransactions() {
			return FNTH_db_get_field( "select count(*) as num from cc_transactions where paid_tstamp is null and cancel_tstamp is null", "num" );
		}
	}
?>
