<?php

/******************************************************************************
 *
 *	PROJECT: Flynax Classifieds Software
 *	VERSION: 4.X
 *	LICENSE: FL4HLD2A8696 - http://www.flynax.com/license-agreement.html
 *	PRODUCT: Real Estate Agency
 *	DOMAIN: gevimmo.com
 *	FILE: RLSTRIPEOLD.CLASS.PHP
 *
 *	The software is a commercial product delivered under single, non-exclusive,
 *	non-transferable license for one domain or IP address. Therefore distribution,
 *	sale or transfer of the file in whole or in part without permission of Flynax
 *	respective owners is considered to be illegal and breach of Flynax License End
 *	User Agreement.
 *
 *	You are not allowed to remove this information from the file without permission
 *	of Flynax respective owners.
 *
 *	Flynax Classifieds Software 2017 |  All copyrights reserved.
 *
 *	http://www.flynax.com/
 *
 ******************************************************************************/

class rlStripe extends reefless
{
	/**
	* @var $subscription
	*/
	protected $subscription;
	
	/**
	* @var $errors
	*/
	protected $errors;
	
	/**
	* @var $request
	*/
	protected $request;
	
	/**
	* @var $account_info
	*/
	protected $account_info;
	
	/**
	* constructor
	* 
	*/
	public function __construct()
	{
		global $account_info;
		
		$this->account_info = &$account_info;
	}
	
	/**
	* set payment options
	* 
	*/
	public function init()
	{
		Stripe\Stripe::setApiKey($GLOBALS['config']['stripe_secret_key']);
		$payment = $_SESSION['complete_payment'];
		
		$this->setOption('item_name', $payment['item_name']);
		$this->setOption('item_id', $payment['item_id']);
		$this->setOption('plan_id', $payment['plan_info']['ID']);
		$this->setOption('total', (float)$payment['plan_info']['Price']);
		$this->setOption('callback_class', $payment['callback']['class']);
		$this->setOption('callback_method', $payment['callback']['method']);
		$this->setOption('plugin', $payment['callback']['plugin']);
		$this->setOption('service', $payment['service']);
		$this->setOption('account_id', $this->account_info['ID']);
		if ($GLOBALS['config']['system_currency_code']) {
			$this->setOption('currency', trim($GLOBALS['config']['system_currency_code']));
		} elseif ($GLOBALS['config']['system_currency']) {
			if ($GLOBALS['config']['system_currency'] == '$') {
				$currency = 'USD';
			} elseif ($GLOBALS['config']['system_currency'] == 'ˆ') {
				$currency = 'EUR';
			} else {
				$currency = $GLOBALS['config']['system_currency'];
			}
			$this->setOption('currency', $currency);	
		}
	}
	
	/**
	* get payment option
	* 
	* @param string $key
	* @return string
	*/
	public function getOption($key = false)
	{
		if (isset($this->request[$key])) {
			return $this->request[$key];
		}
		
		return null;
	}
	
	/**
	* set payment option
	* 
	* @param string $key
	* @param string $value
	*/
	public function setOption($key = false, $value = false)
	{
		if ($key) {
			$this->request[$key] = $value;
		}
	}

	/**
	* call payment process
	* 
	*/
	public function callBack()
	{
		$this->setOption('email', $_POST['email'] ? $_POST['email'] : $this->account_info['Mail']);
		$this->setOption('token', $_POST['stripe-token']);
		$this->setOption('currency', $GLOBALS['config']['system_currency_code'] ? $GLOBALS['config']['system_currency_code'] : 'USD');
		$sql = "SELECT * FROM `" . RL_DBPREFIX . "listing_plans` WHERE `ID` = '".$this->getOption('plan_id')."' LIMIT 1";
		$plan_info = $this->getRow($sql);

		if ($plan_info['stripe_subscription'] && $plan_info['stripe_subscription_interval']) {
			$this->setSubscription();
			$this->setOption('plan', $plan_info['Key']);

			$this->createSubscriptionPayment();
		} else {
			$this->createSinglePayment();
		}
	}
	
	/**
	* create single payment; 
	* 
	*/
	public function createSinglePayment()
	{
		try {
			$charge = Stripe\Charge::create(array(
			  "amount" => $this->getOption('total') * 100,
			  "currency" => $this->getOption('currency'),
			  "card" => $this->getOption('token'),
			  "description" => $this->getOption('item_name') . ' (' . $this->getOption('email') . ')')
			);

			if ( $charge->paid == true && $charge->id) {
				$callback_class = $this->getOption('callback_class');
				$callback_method = $this->getOption('callback_method');
					
				$this->loadClass(str_replace('rl', '', $callback_class), null, $this->getOption('plugin') ? $this->getOption('plugin') : false);
				$GLOBALS[$callback_class]->$callback_method($this->getOption('item_id'), $this->getOption('plan_id'), $this->getOption('account_id'), $charge->id, 'stripe', $this->getOption('total'));
			}
		}  catch(Stripe\Error\Card $e)  {
			$this->errors[] = $e->getMessage();
		}	                                                                  
	}
	
	/**
	* create subscription payment
	* 
	*/
	public function createSubscriptionPayment()
	{
		$sql = "SELECT * FROM `" . RL_DBPREFIX . "listing_plans` WHERE `ID` = '".$this->getOption('plan_id')."' LIMIT 1";
		$plan_info = $this->getRow($sql);
			
		try {
			$customer = Stripe\Customer::create(array(
				"card" => $this->getOption('token'),
				"plan" => $this->getOption('plan'),
				"email" => $this->getOption('email'))
			);

			$txn_id = $customer->cards->data[0]->id;
			$item = $this->getOption('plan_id') . '|' . // 0 
					$this->getOption('item_id') . '|' . // 1 
					$this->getOption('account_id') . '|' . // 2 
					$this->getOption('total') . '|' . // 3
					$this->getOption('callback_class') . '|' . // 4
					$this->getOption('callback_method') . '|' . // 5
					RL_LANG_CODE . '|' . // 6
					$this->getOption('plugin'); // 7

			$item = urlencode(base64_encode($item));

			if ($customer->subscriptions && $customer -> id) {
				$insert = array(
						'Txn_ID' => $txn_id,
						'Date' => 'NOW()',
						'Account_ID' => $this->getOption('account_id'),
						'Plan_ID' => $this->getOption('plan_id'),
						'Customer_ID' => $customer->id,
						'Item_ID' => $this->getOption('item_id'),
						'Subscription_ID' => $customer->subscriptions->data[0]->id,
						'Count' => 0,
						'Item_data' => $item
					);

				if ($rlActions->insertOne($insert, 'stripe_subscriptions')) {
					$sql = "UPDATE `" . RL_DBPREFIX . "listings` SET `stripe_subscription_id` = '{$customer->subscriptions->data[0]->id}' WHERE `ID` = '".$this->getOption('item_id')."' LIMIT 1";
					$this->query($sql);
					
					$callback_class = $this->getOption('callback_class');
					$callback_method = $this->getOption('callback_method');

					$this->loadClass(str_replace('rl', '', $callback_class), null, $this->getOption('plugin') ? $this->getOption('plugin') : false);
					$GLOBALS[$callback_class]->$callback_method($this->getOption('item_id'), $this->getOption('plan_id'), $this->getOption('account_id'), $txn_id, 'stripe', $this->getOption('total'));
				}
			}
		}  catch(Stripe\Error\Card $e) {
			$this->errors[] = $e->getMessage();
		}
	}

	/**
	* create subscription plan
	* 
	* @param string $key
	* @param float $total
	* @param string $name
	* @param string $period
	* 
	* @return mixed
	*/
	public function createSubscriptionPlan($key = false, $total = false, $name = false, $period = 'month')
	{
		if(!$key || !$total || !$period) {
			return;
		}
		$plans = $this->getPlans();

		if (in_array($key, $plans)) {
			return;
		}
		$plan = Stripe\Plan::create(array(
			"amount" => (float)$total * 100,
			"interval" => $period,
			"name" => $name,
			"currency" => $GLOBALS['config']['stripe_currency'],
			"id" => $key)
		);
		
		return $plan;
	}

	/**
	* delete subscription plan
	* 
	* @param string $key
	*/
	public function deleteSubscriptionPlan($key = false)
	{
		if (!$key) {
			return;
		}
		$plan = Stripe\Plan::retrieve($key);
		$plan->delete();
	}

	/**
	* cancel subscription for specific plan
	* 
	* @param mixed $subscription_id
	* @param integer $plan_id
	*/
	public function ajaxCancelSubscription($subscription_id = false, $plan_id = false)
	{
		global $_response;

		$sql = "SELECT * FROM `" . RL_DBPREFIX . "stripe_subscriptions` WHERE `Subscription_ID` = '{$subscription_id}' LIMIT 1";
		$subscription_info = $this->getRow($sql);

		$customer = Stripe\Customer::retrieve($subscription_info['Customer_ID']);
		$action = $customer->subscriptions->retrieve($subscription_id)->cancel();

		$sql = "UPDATE `" . RL_DBPREFIX . "listings` SET `stripe_subscription_id` = '' WHERE `ID` = '{$subscription_info['Item_ID']}' LIMIT 1";
		$this->query($sql);
		
		$sql = "UPDATE `" . RL_DBPREFIX . "stripe_subscriptions` SET `Status` = 'canceled' WHERE `ID` = '{$subscription_info['ID']}' LIMIT 1";
		$this->query($sql);

		if ($action) {
			$_response->script("
					$('#{$subscription_id}-{$plan_id}-stripe').remove();
					printMessage('notice', '{$GLOBALS['lang']['stripe_unsubscription_success']}');
				");
		} else {
			$_response->script("
					printMessage('error', '{$GLOBALS['lang']['stripe_unsubscription_failed']}');
				");
		}

		return $_response;
	}

	/**
	* get plans available on stripe service
	* 
	*/
	public function getPlans()
	{
		$plans = array();
		$response = Stripe\Plan::all();

		if ($response->data) {
			foreach($response->data as $k => $v) {
				$plans[] = $v->id;
			}
		}

		return $plans;
	}

	/**
	* prepare data to save
	* 
	* @param mixed $data
	*/
	public function prepareDataToSave(&$data)
	{
		$data['stripe_subscription'] = $_POST['stripe_subscription'] ? 1 : 0;

		if ($_POST['stripe_subscription']) {
			$data['stripe_subscription_interval'] = $_POST['stripe_subscription_interval'];
			$data['stripe_subscription_count'] = (int)$_POST['stripe_subscription_count'];
		} else {
			$data['stripe_subscription_interval'] = '';
			$data['stripe_subscription_count'] = 0;
		}
	}

	/**
	* get card types
	* 
	* @param boolean $output
	* @return array
	*/
	public function getCardTypes($output = true)
	{
		$types = array(
				'visa' => "Visa",
				'mastercard' => "MasterCard",
				'american_express' => "American Express",
				'discover' => "Discover",
				'diners_club' => "Diners Club",
				'jcb' => "JCB"
			);

		if ($output) {
			$GLOBALS['rlSmarty']->assign_by_ref('card_types', $types);
			return;
		}

		return $types;
	}

	/**
	* get subscription intervals
	* 
	* @param boolean $output
	* @return array
	*/
	public function getSubscriptionIntervals($output = true)
	{
		$intervals = array(
				'week' => $GLOBALS['lang']['stripe_interval_week'],
				'month' => $GLOBALS['lang']['stripe_interval_month'],
				'year' => $GLOBALS['lang']['stripe_interval_year']
			);

		if ($output) {
			$GLOBALS['rlSmarty']->assign_by_ref('subscription_intervals', $intervals);
			return;
		}

		return $intervals;
	}

	/**
	* zet subscription mode
	* 
	* @param boolean $mode
	*/
	public function setSubscription($mode = true)
	{
		$this->subscription = (bool)$mode;
	}
	
	/**
	* chack subscription mode
	* 
	* @return boolean
	* 
	*/
	public function isSubscription()
	{
		if ($this->subscription) {
			return true;
		}
		
		return false;
	}
	
	/**
	* check for errors
	* 
	* @return boolean
	* 
	*/
	public function hasError()
	{
		if ($this->errors) {
			return true;
		}
		
		return false;
	}
	
	/**
	* set dealer credentials 
	* 
	*/
	public function setDealerCredentials($item_id = false)
	{
		$sql = "SELECT `T1`.`ID`, `T2`.`shc_stripe_enable`, `T2`.`shc_stripe_publishable_key`, `T2`.`shc_stripe_secret_key` ";
		$sql .= "FROM `" . RL_DBPREFIX . "shc_orders` AS `T1` ";
		$sql .= "LEFT JOIN `" . RL_DBPREFIX . "accounts` AS `T2` ON `T1`.`Dealer_ID` = `T2`.`ID` ";
		$sql .= "WHERE `T1`.`ID` = '" .$item_id . "' ";
		$sql .= "LIMIT 1";

		$dealer_info = $this->getRow($sql);

		if ($dealer_info['shc_stripe_publishable_key'] && $dealer_info['shc_stripe_secret_key']) {
			$GLOBALS['config']['stripe_publishable_key'] = $dealer_info['shc_stripe_publishable_key'];
			$GLOBALS['config']['stripe_secret_key'] = $dealer_info['shc_stripe_secret_key'];
		} else {
			$this->errors[] = $GLOBALS['lang']['stripe_seller_payment_details_empty'];
		}
	}

	public function isConfigured()
	{
		if ($GLOBALS['config']['stripe_publishable_key'] && $GLOBALS['config']['stripe_secret_key']) {
			return true;
		}
		
		return false;
	}
	
	public function getSubscriptionByID($subscription_id = false)
	{
		if (!$subscription_id) {
			return false;
		}

		$sql = "SELECT * FROM `" . RL_DBPREFIX . "stripe_subscriptions` WHERE `Subscription_ID` = '".$subscription_id."' LIMIT 1";
		$subscription_info = $this->getRow($sql);
		
		if ($subscription_info) {
			$subscription_info['Item_data'] = explode("|", urldecode(base64_decode($subscription_info['Item_data'])));
		}

		return $subscription_info;
	}
	
	/**
	* get errors
	* 
	* @return array;
	* 
	*/
	public function getErrors()
	{
		if ($this->errors) {
			return $this->errors;
		}

		return array();
	}
}