<?php
if (!class_exists('ChangeRanks')) :

class ChangeRanks{
	private $ranks_data;
	private $do_break;
	private $bonus_enabled = FALSE;
	private $ranksPro = false;

	public function __construct($affiliates_ids_in=array()){
		/*
		 * @param [array - selected affiliates]
		 * @return none
		 */
		global $indeed_db;
		$this->ranks_data = $indeed_db->get_ranks(TRUE);
		$this->bonus_enabled = $indeed_db->is_magic_feat_enable('bonus_on_rank');
		if ($this->ranks_data){
			$this->ranks_data = uap_reorder_ranks($this->ranks_data);/// sort array by order attr

			/// RanksPro
			$minimumDate = '';
			$this->ranksPro = get_option('uap_ranks_pro_enabled');
			if ($this->ranksPro){
					$this->ranksPro = (get_option('uap_default_achieve_calculation')=='limited') ? true : false;
			}
			if ($this->ranksPro){
					$minimumDate = get_option('uap_achieve_period');
					$minimumDate = strtotime("-$minimumDate day", time());
			}

			$affiliates = [];
			if ( $this->ranksPro ){
				  $allAffiliates = $indeed_db->getAffiliatesForCheckRanks($affiliates_ids_in);
			}
			$affiliatesWithValues = $indeed_db->get_affiliates_from_referrals($affiliates_ids_in, $minimumDate);/// get affiliates with at least one referral verified

			if ( !empty( $allAffiliates ) ){
					foreach ( $allAffiliates as $key => $array ){
							if ( isset( $affiliatesWithValues[$key]['total_amount'] ) ){
									$allAffiliates[$key]['total_amount'] = $affiliatesWithValues[$key]['total_amount'];
							}
							if ( isset( $affiliatesWithValues[$key]['total_referrals'] ) ){
									$allAffiliates[$key]['total_referrals'] = $affiliatesWithValues[$key]['total_referrals'];
							}
					}
			} else {
					$allAffiliates = $affiliatesWithValues;
			}

			if ($allAffiliates){
				foreach ($allAffiliates as $id=>$array){
					$current_rank = $indeed_db->get_affiliate_rank($id);
					$this->check($id, $array, $current_rank);
				}
			}
		}
	}

	/**
	 * @param int
	 * @param array
	 * @param int
	 * @return none
	 */
	private function check($affiliate_id = 0, $affiliate_data=array(), $current_rank=0)
	{
			global $indeed_db;
			if (empty($affiliate_data['total_amount'])){
					$affiliate_data['total_amount'] = 0;
			}
			if (empty($affiliate_data['total_referrals'])){
					$affiliate_data['total_referrals'] = 0;
			}

			$this->do_break = FALSE;
			$current_rank_detalis = $indeed_db->get_rank($current_rank);
			$ranks = $this->ranks_data;
			$ranks_num = count($ranks);
			$affiliateRankBeforeUpdate = $current_rank;

			if ( empty( $this->ranksPro ) ){
					foreach ($ranks as $key=>$object){
						if ( !empty($object->rank_order) && $object->rank_order<=$current_rank_detalis['rank_order'] ){
								unset($ranks[$key]);
						}
					}
			}

			/// LOOP THROUGH RANKS
			foreach ($ranks as $key=>$object){
					if ( empty( $object->achieve ) && !$this->ranksPro ){
							continue;
					}
					$rank_id = $object->id;
					if ( isset( $object->achieve ) && $object->achieve !== false ){
							$achieve = json_decode($object->achieve, TRUE);
					}
					if (empty($achieve)){
							$achieve = [
								"i" 				=> 1,
								"type_1" 		=> "referrals_number",
								"value_1" 	=> 0
							];
					}

					/// LOOP RANK THROUGH CONDITIONS
					/*
							achieve conditions exemple :
							[
									'type_1' 			=> 'referral_number',
									'value_1'			=> 100,
									'type_2'			=> 'total_amount',
									'value_2'			=> 2000,
									'relation_2'	=> 'and'
							]
					*/
					$doIt = false;
					for ( $i=1; $i<=$achieve['i']; $i++ ){
							$condition = $this->compare($affiliate_data, $achieve['type_' . $i], $achieve['value_' . $i]);
							$condition = apply_filters( 'uap_filter_change_rank_achieve_compare_result', $condition, $affiliate_id, $affiliate_data, $achieve['type_' . $i], $achieve['value_' . $i] );
							
							if ( !empty( $achieve['relation_' . $i] ) ){
								if ( $achieve['relation_' . $i] === 'and' ){
									$doIt = ( $doIt && $condition );
								} else if ( $achieve['relation_' . $i] === 'or' ){
									$doIt = ( $doIt || $condition );
								}
							} else {
								$doIt = $condition;
							}
					}
					if ( $doIt ){
							$this->set_new_rank( $affiliate_id, $rank_id, $affiliateRankBeforeUpdate );
					} else if ( !$this->ranksPro ){
							$this->set_break();
					}

					if ( $this->do_break ){
							break;
					}
			}

			// send notification if its case
			$currentRank = $indeed_db->get_affiliate_rank( $affiliate_id );
			$currentRank = (int)$currentRank;
			$affiliateRankBeforeUpdate = (int)$affiliateRankBeforeUpdate;

			if ( $affiliateRankBeforeUpdate !== $currentRank ){
					$uid = $indeed_db->get_uid_by_affiliate_id( $affiliate_id );
					uap_send_user_notifications( $uid, 'rank_change', $currentRank );//send notification to user
					uap_send_user_notifications( $uid, 'admin_on_aff_change_rank', $currentRank );//send notification to admin
					// pay the bonus
					$indeed_db->pay_bonus_for_rank( $uid, $currentRank );
			}
	}

	private function compare($u_data, $r_type, $r_value){
		/*
		 * @param user data, achieve type, achieve value ... array, string, string
		 * @return int 0 or 1
		 */
		if ($r_type=='referrals_number'){
			if ($r_value<=$u_data['total_referrals']){
				return 1;
			}
		} else if ($r_type=='total_amount'){
			if ($r_value<=$u_data['total_amount']){
				return 1;
			}
		}
		return 0;
	}

	private function set_new_rank( $affiliate_id, $rank_id, $affiliateRankBeforeUpdate ){
		/*
		 * @param int, int
		 * @return none
		 */
		global $indeed_db;
		$currentRank = $indeed_db->get_affiliate_rank($affiliate_id);

		$currentRank = (int)$currentRank;
		$rank_id = (int)$rank_id;
		$affiliateRankBeforeUpdate = (int)$affiliateRankBeforeUpdate;

		if ($currentRank==$rank_id){
				/// affilaite already has this rank
				return;
		}

		/// CHANGE RANK
		$indeed_db->update_affiliate_rank($affiliate_id, $rank_id);

		if ( $affiliateRankBeforeUpdate === $rank_id ){
				return;
		}
		/// PAY THE BONUS
		//$uid = $indeed_db->get_uid_by_affiliate_id($affiliate_id);
		//$indeed_db->pay_bonus_for_rank($uid, $rank_id);
		/// SEND NOTIFICATIONS
		//uap_send_user_notifications($uid, 'rank_change', $rank_id);//send notification to user
		//uap_send_user_notifications($uid, 'admin_on_aff_change_rank', $rank_id);//send notification to admin

	}

	private function set_break(){
		/*
		 * @param none
		 * @return none
		 */
		 $this->do_break = TRUE;
	}

}

endif;
