<?php

class Spots {

	/**
	 * @param $f3 \Base
	 */
	public function getIndex($f3){

		$encoded_url = $f3->get('PARAMS.url');
		if (empty($encoded_url)){
			$f3->error(404);
		}

		$spotsData = $this->_getSpotsData($f3, $encoded_url);
		if (empty($spotsData)){
			$f3->error(404);
		}
		$f3->set('res_sales',$spotsData);
		$f3->set('title', $spotsData[0]['site_name']);
		$f3->set('alert', '');

		$config = new \Models\Config();
		$config->load(array('_id = ?', 1));
		if ($config->dry()) return;
		$paymentMethods = array();
		if (!empty($config->paypal_api_signature)) $paymentMethods[] = array('name' => 'PayPal', 'value' => 'paypal');
		if (!empty($config->stripe_secret_key)) $paymentMethods[] = array('name' => $f3->get('lang_credit_card_via_stripe'), 'value' => 'stripe');
		$f3->set('stripe_publishable_key', $config->stripe_publishable_key);
		$f3->set('payment_methods', $paymentMethods);

		echo Template::instance()->render('spots.html');
	}


	/**
	 * @param $f3 \Base
	 * @param $params
	 */
	public function postPurchase($f3, $params){
		$saleId = $f3->get('PARAMS.id');
		$qty = $f3->get('PARAMS.qty');
		$method = $f3->get('PARAMS.method');

		$sale = new \Models\Sale();
		$sale->load(array('status = 1 AND _id = ?', $saleId, null, 60));
		if ($sale->dry()) $f3->error(404);

		$response = '';
		$p = new Pay();
		if ($method == 'paypal'){
			$response = $p->paypalPurchase($f3, $sale, $qty);
		} elseif ($method == 'stripe'){
			$response = $p->stripePurchase($f3, $sale, $qty);
		}

		// Record click
		self::_insertStatsQueue($f3, 0, 0, 1, null, null, null, null, $saleId);

		echo $response;
	}


	/** Used by PayPal
	 * @param $f3 \Base
	 * @param $params
	 */
	public function getPurchaseReturn($f3, $params){
		$p = new Pay();

		$method = $f3->get('PARAMS.method');
		$saleId = $f3->get('PARAMS.id');
		$sale = new \Models\Sale();
		$sale->load(array('status = 1 AND _id = ?', $saleId, null, 60));
		if ($sale->dry()) $f3->error(404);

		if ($method == 'stripe'){
			$response = $p->stripeCompletePurchase($f3, $sale);
		} elseif ($method == 'nopayment') {
			$response = $p->noPaymentCompletePurchase($f3, $sale);
		} else {
			$response = $p->paypalCompletePurchase($f3);
		}

		// Error - show spots with alert
		if (!empty($response)){

			$spotsData = $this->_getSpotsData($f3, $sale->site_key);
			if (empty($spotsData)){
				$f3->error(404);
			}
			$f3->set('res_sales',$spotsData);
			$f3->set('title', $spotsData[0]['site_name']);
			$f3->set('alert', $response);

			$config = new \Models\Config();
			$config->load(array('_id = ?', 1));
			if ($config->dry()) return;
			$paymentMethods = array();
			if (!empty($config->paypal_api_signature)) $paymentMethods[] = array('name' => 'PayPal', 'value' => 'paypal');
			if (!empty($config->stripe_secret_key)) $paymentMethods[] = array('name' => $f3->get('lang_credit_card_via_stripe'), 'value' => 'stripe');
			$f3->set('stripe_publishable_key', $config->stripe_publishable_key);
			$f3->set('payment_methods', $paymentMethods);

			echo Template::instance()->render('spots.html');

			return;
		}

		$this->_insertStatsSale($saleId);

		$token = $f3->get('GET.token');
		if (empty($token)) $token = $f3->get('PARAMS.token');

		$saleRecord = new \Models\Salerecord();
		$saleRecord->load(array('transaction_reference = ?', $token));

		$f3->set('sale_id',$saleId);
		$f3->set('salerecord_id',$saleRecord->_id);
		$f3->set('title',$saleRecord->sale_id->title);

		echo Template::instance()->render('spots-account.html');
	}


	/**
	 * @param $f3 \Base
	 * @param $params
	 */
	public function postCheckExistingAccount($f3, $params){

		$user = new \Models\User();
		$user->load(array("mail = ? AND enabled = 1 AND password IS NOT NULL", $f3->get('POST.mail')));
		if ($user->dry()) {
			echo json_encode(array('exists' => 'false'));
		} else {
			echo json_encode(array('exists' => 'true'));
		}
	}


	/** Setup new advertiser account if necessary, create base ad
	 * @param $f3 \Base
	 * @param $params
	 */
	public function postPurchaseAccount($f3, $params){

		$response_array = array();
		$response_array['status'] = '';

		if (!$f3->get('POST.mail')){
			$response_array['status'] = 'error';
			$response_array['msg'] = $f3->get('lang_something_went_wrong_setting_up_your_new_account__please_contact_us_to_correct_it__thanks_');
			echo json_encode($response_array);
			return;
		}

		$sale = new \Models\Sale();
		$sale->load(array('_id=?', $f3->get('PARAMS.saleid')));
		if ($sale->dry()){
			$response_array['status'] = 'error';
			$response_array['msg'] = $f3->get('lang_something_went_wrong_setting_up_your_new_account__please_contact_us_to_correct_it__thanks_');
			echo json_encode($response_array);
			return;
		}

		$saleRecord = new \Models\Salerecord();
		$saleRecord->load(array('_id=?', $f3->get('PARAMS.salerecordid')));
		if ($saleRecord->dry()){
			$response_array['status'] = 'error';
			$response_array['msg'] = $f3->get('lang_something_went_wrong_setting_up_your_new_account__please_contact_us_to_correct_it__thanks_');
			echo json_encode($response_array);
			return;
		}

		//Check if ad already setup
		$ad = new \Models\Ad();
		$ad->load(array('sale_record=?',$f3->get('PARAMS.salerecordid')));
		if (!$ad->dry()){
			$response_array['status'] = 'success';
			$response_array['msg'] = '';
			echo json_encode($response_array);
			return;
		}

		$user = new \Models\User();
		$user->load(array("mail = ? AND enabled = 1 AND password IS NOT NULL", $f3->get('POST.mail')));
		if ($user->dry()){
			$user = new \Models\User();
			try {
				$user->username = $f3->get('POST.mail');
				$user->enabled = 1;
				$user->password = $f3->get('POST.password');
				$user->mail = $f3->get('POST.mail');
				$user->api = sha1(mt_rand().$f3->get('POST.mail'));
				$user->role = 1;
				$user->receive_mail = 1;
				$user->save();
				$user->load(array("mail = ? AND enabled = 1 AND password IS NOT NULL", $f3->get('POST.mail')));
			} catch (Exception $e){
				Utils::Logger('[postPurchaseAccount]Error setting up new advertiser account - '.$e);
				$response_array['status'] = 'error';
				$response_array['msg'] = $f3->get('lang_something_went_wrong_setting_up_your_new_account__please_contact_us_to_correct_it__thanks_');
				echo json_encode($response_array);
				return;
			}
		}

		$saleRecord->buyer_email = $user->mail;
		$saleRecord->user_id = $user->_id;
		$saleRecord->save();
		$saleRecord->load(array('_id=?', $f3->get('PARAMS.salerecordid')));

		//$sale->pricing_type;
		$impressions_limit_num = 1000000000;
		$clicks_limit_num = 1000000000;
		$limit_time = 365;
		$qty = $saleRecord->quantity;
		switch ($sale->pricing_type){
			case 'cpm':
				$impressions_limit_num = 1000 * $qty;
				break;
			case 'cpc':
				$clicks_limit_num = $qty;
				break;
			case 'month':
				$limit_time = 30;
				break;
			case '3month':
				$limit_time = 90;
				break;
			case '6month':
				$limit_time = 180;
				break;
			case 'week':
				$limit_time = 7;
				break;
			case 'year':
				$limit_time = 365;
				break;
			case 'day':
				$limit_time = 1;
				break;
		}

		try{
			// Create base ad
			$ad = new \Models\Ad();
			$ad->title = $f3->get('lang_sales').' - '.substr($sale->title, 0, 20).'... '.date('Y-m-d H:i:s');
			$ad->status = 0;
			$ad->approved = 0;
			$ad->type = $sale->type;
			$ad->user_id = $user->_id;
			$ad->advertiser = $user->_id;
			$ad->sale = $sale->_id;
			$ad->sale_record = $saleRecord->_id;
			$ad->impressions_limit_num = $impressions_limit_num;
			$ad->clicks_limit_num = $clicks_limit_num;
			$ad->limit_time = $limit_time;
			$ad->last_updated = time();
			$ad->save();
		} catch (Exception $e){
			Utils::Logger('[postPurchaseAccount]Error setting up new base ad - '.$e);
			$response_array['status'] = 'error';
			$response_array['msg'] = $f3->get('lang_something_went_wrong_setting_up_your_new_account__please_contact_us_to_correct_it__thanks_');
			echo json_encode($response_array);
			return;
		}

		$ad = new \Models\Ad();
		$ad->load(array('sale_record=?', $saleRecord->_id));
		$ad->dry() ? $response_array['msg'] = 'index.php?login' : $response_array['msg'] = 'index.php?ads&edit&'.$ad->_id;

		Utils::Logger('[postPurchaseAccount]msg='.$response_array['msg'],'debug');

		Email::sendAdvertiserSpotPurchase($sale, $saleRecord, $ad);

		$response_array['status'] = 'success';
		$response_array['msg'] = '';
		echo json_encode($response_array);
		return;
	}



	/**
	 * @param $f3 \Base
	 * @param $siteKey string
	 */
	private function _getSpotsData($f3, $siteKey){

		$ip=$f3->get('IP');
		if ((empty($ip)) || ($ip == '::1')) $ip = '127.0.0.1';
		$cacheKey = ip2long($ip).'_spots_'.$siteKey.'.code';
		$cache = \Cache::instance();
		$res_sales = $cache->get($cacheKey);
		if (!empty($res_sales)){
			self::_insertStatsQueue($f3, 0, 1, 0, null, null, null, $siteKey);
			return ($res_sales);
		}

		$res_sales = new \Models\Sale();
		$sales = $res_sales->find(array('status = 1 AND site_key = ?', $siteKey));
		if (empty($sales)) return null;

		$ad_types = Sales::adTypes($f3);
		$currencies = Sales::currencies($f3);
		$pricing_types = Sales::pricingTypes($f3);

		$res_sales = array();
		if ($sales){
			foreach ($sales as $sale) {
				$res_sale = array();
				$res_sale['id'] = $sale->_id;
				$res_sale['site_name'] = $sale->site_name;
				$res_sale['site_url'] = $sale->site_url;
				$res_sale['site_contact_url'] = $sale->site_contact_url ? $sale->site_contact_url : $sale->site_url;
				$res_sale['title'] = $sale->title;
				$res_sale['type'] = $ad_types[$sale->type]['name'];
				if ((!empty($sale->banners_width)) && (!empty($sale->banners_height))){
					$res_sale['dimensions'] = $sale->banners_width . 'w x ' . $sale->banners_height . 'h';
				} else {
					$res_sale['dimensions'] = '';
				}
				$res_sale['pricing_cost'] = number_format($sale->pricing_cost, 2);
				$res_sale['pricing_currency'] = $currencies[$sale->pricing_currency]['name'];
				$res_sale['pricing_type'] = $pricing_types[$sale->pricing_type]['name'];
				$res_sale['pricing_type_code'] = $sale->pricing_type;
				$res_sale['spots_left'] = $sale->max_spots;
				$res_sale['spot_image'] = empty($sale->spot_image_url) ? '' : '<a href="'.$sale->spot_image_url.'" class="img-responsive img-thumbnail" data-type="image" data-toggle="lightbox" data-title="'.$sale->title.'"><img src="'.$sale->spot_image_url.'" '.$this->_getThumbnailSize($sale->spot_image_url).' /></a>';
				if ($sale->pricing_type == 'cpm'){
					$res_sale['pricing_type_input'] = $f3->get('lang_impressions');
				} elseif($sale->pricing_type == 'cpc'){
					$res_sale['pricing_type_input'] = $f3->get('lang_clicks');
				} else {
					$res_sale['pricing_type_input'] = '';
				}
				if (empty($res_sale['spot_image'])){
					switch ($sale->type){
						case 'banner':
							$res_sale['spot_image'] = '<i class="fa fa-picture-o fa-9x"></i>';
							break;
						case 'textlink':
							$res_sale['spot_image'] = '<i class="fa fa-external-link fa-9x"></i>';
							break;
						case 'video':
							$res_sale['spot_image'] = '<i class="fa fa-video-camera fa-9x"></i>';
							break;
						case 'freeform':
							$res_sale['spot_image'] = '<i class="fa fa-square-o fa-9x"></i>';
							break;
					}
				}
				$res_sales[] = $res_sale;
			}
		}

		$cache->set($cacheKey, $res_sales, 3600);
		self::_insertStatsQueue($f3, 1, 1, 0, null, null, null, $siteKey);

		return ($res_sales);
	}


	/**
	 * @param $sale_id int
	 */
	private function _insertStatsSale($sale_id){

		$stat_sale_res = new \Models\Statsale();
		$stat_sale = $stat_sale_res->findone(array('date = ? and sale_id = ?',date('Ymd'),$sale_id));

		if ($stat_sale){
			$stat_sale->sales += 1;
		} else {
			$stat_sale = new \Models\Statsale();

			$stat_sale->date = date('Ymd');
			$stat_sale->sale_id = $sale_id;
			$stat_sale->sales = 1;
		}

		$stat_sale->save();

	}


	/**
	 * @param $f3 \Base
	 * @param $u int Uniques
	 * @param $i int Impressions
	 * @param $c int Clicks
	 * @param $ad_id int Ad Id
	 * @param $group_id int Group Id
	 * @param $keyword_id int Keyword Id
	 * @param $site_key string Site Key
	 * @param $sale_id int Sale Id
	 */
	private static function _insertStatsQueue($f3, $u=0, $i=1, $c=0, $ad_id=null, $group_id=null, $keyword_id=null, $site_key=null, $sale_id=null, $hostname=null, $referer=null){
		try{
			$userAgent=empty($_SERVER['HTTP_USER_AGENT']) ? '' : $_SERVER['HTTP_USER_AGENT'];

			//Check bot
			if ((!empty($userAgent)) && (self::_is_bot($userAgent))) return;

			$ip=$f3->get('IP');
			if ($ip == '::1') $ip = '127.0.0.1';

			$hostname=empty($_SERVER['HTTP_HOST']) ? '' : $_SERVER['HTTP_HOST'];
			$referer=empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];

			$f3->get('DB')->exec('INSERT INTO mysa_stats_q (dt, ad_id, group_id, keyword_id, site_key, sale_id, u, i, c, ip, hostname, referer, agent) VALUES(:dt, :ad_id, :group_id, :keyword_id, :site_key, :sale_id, :u, :i, :c, :ip, :hostname, :referer, :agent)', array(':dt' => time(), ':ad_id' => $ad_id,':group_id' => $group_id, ':keyword_id' => $keyword_id, ':site_key' => $site_key, ':sale_id' => $sale_id, ':u' => $u, ':i' => $i, ':c' => $c, ':ip' => ip2long($ip), ':hostname' => $hostname, ':referer' => $referer, ':agent' => $userAgent));
		} catch (Exception $e){
			\Utils::Logger('[_insertStatsQueue]Error inserting stat - '.$e);
		}
	}


	/*
	*
	* @param mixed $user_agent
	* @return returns true if the user agent is a bot
	*/
	private static function _is_bot($user_agent) {
		$user_agent = strtolower($user_agent);

		//array of bot strings to check for
		$bot_strings = array('google', 'bot', 'yahoo', 'spider', 'bing', 'archiver', 'curl', 'python', 'baidu', 'perl', 'sphere', 'pear', 'java', 'wordpress', 'crawl', 'yandex', 'monitor', 'mechanize', 'facebook', 'ask');
		foreach ($bot_strings as $bot) {
			if (strpos($user_agent, $bot) !== false)
				return true;
		}

		return false;
	}


	/**
	 * @param $image_url
	 * @return string
	 */
	private function _getThumbnailSize($image_url){
		$maxHeight = 160;
		$maxWidth = 200;
		list($width, $height, $type, $attr) = getimagesize($image_url);
		$ratio = min($maxHeight / $height, $maxWidth / $width);
		$newHeight = ceil($height * $ratio);
		$newWidth = ceil($width * $ratio);
		return ('width = "'.$newWidth.'" height="'.$newHeight.'"');
	}

}