<?php
defined('BASEPATH') OR exit('No direct script access allowed');
header('Content-Type: application/json');
date_default_timezone_set('Europe/London');
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: api-token,user-api-token,device-name,device");
header("Access-Control-Expose-Headers: content-disposition");
ini_set('memory_limit', '-1');
set_time_limit(60000);

class AdminAPI extends MY_Controller {

	function __construct() {
		parent::__construct();
		$this->load->model('PBReusableModel_Security','appsecurity');
		$this->load->model('PBReusableModel_Analytics','analytics');
		$this->load->model('PBReusableModel_Partners','partners');
		$this->load->model('PBReusableModel_Global','globals');
		$this->load->model('PBReusableModel_User','users');
		$this->load->model('PBReusableModel_Notifications','notifications');
		$this->load->model('PBReusableModel_CSVExport','csv');
		$this->load->model('PBReusableModel_Wallet','wallet');
		$this->load->model('PBReusableModel_Subscriptions','subscriptions');
		$this->load->model('Auth_Model', 'auth');

	}

    public function awardTokensToUsers($total,$limit,$offset) {
        $status = $this->wallet->addTokensToUsers($total,$limit,$offset);
        if($status) {
            echo json_encode(array('success' => true, 'message' => 'Tokens Added!', 'context' => 'The Tokens were add to the users accounts'));
        } else {
            echo json_encode(array('success' => false, 'message' => 'Tokens could not be added!', 'context' => 'The Tokens were not added to the users accounts'));
        }
    }

    public function hello_world() {
        echo json_encode(array('success' => true, 'message' => 'Hello World!', 'context' => 'The Admin API is working and ready to go'));
    }

	public function checkPasswordEncryption() {
		$result = $this->users->checkPasswordEncryption();
		echo json_encode(array(
			'result' => $result,
			'sent_pass' => $this->input->post('passwd')
		));
	}

    public function testGenerationOfTokensAtSameTime() {
		$tokens = $this->appsecurity->generateMultipleTokens($this->input->request_headers());
        echo json_encode(array(
			'success' => true,
			'message' => 'Tested the creation of multiple tokens simultaneously.',
			'context' => 'Test to ensure no two tokens can be the same',
			'token_data' => $tokens
		));
    }

	public function getTopViewedArticles() {
        $authenticated = $this->authenticateCall();
        if($authenticated) {
            $top_articles = $this->analytics->getTopArticlesByViews();
            echo json_encode(array(
                'success' => true,
                'message' => 'Successfully grabbed the data.',
                'context' => 'Everything was fine',
                'list' => $top_articles
            ),JSON_NUMERIC_CHECK);
        }
    }

    public function getTopViewedPodcasts() {
        $authenticated = $this->authenticateCall();
        if($authenticated) {
            $top_podcasts = $this->analytics->getTopPodcastsByViews();
            echo json_encode(array(
                'success' => true,
                'message' => 'Successfully grabbed the data.',
                'context' => 'Everything was fine',
                'list' => $top_podcasts
            ),JSON_NUMERIC_CHECK);
        }
    }

    public function getTopViewedVideos() {
        $authenticated = $this->authenticateCall();
        if($authenticated) {
            $top_videos = $this->analytics->getTopVideosByViews();
            echo json_encode(array(
                'success' => true,
                'message' => 'Successfully grabbed the data.',
                'context' => 'Everything was fine',
                'list' => $top_videos
            ),JSON_NUMERIC_CHECK);
        }
    }

    public function getUsersStats() {
        $authenticated = $this->authenticateCall();
        if($authenticated) {
            $total_guests = $this->analytics->countGuests();
            $total_converted = $this->analytics->countFullUsers();
            $total_users = $total_guests['total']+$total_converted['total'];
            echo json_encode(array(
                'success' => true,
                'message' => 'Successfully counted the data for the chosen analytic.',
                'context' => 'Everything was fine',
                'total_users' => (int)$total_users,
                'total_guests' => (int)$total_guests['total'],
                'total_full' => (int)$total_converted['total'],
            ));
        }
    }

    public function getMarketplaceStats() {
        $authenticated = $this->authenticateCall();
        if($authenticated) {
            $total_credits_purchased = $this->analytics->countPurchasedCredits();
            $total_credits_spent = $this->analytics->countSpentCredits();
            $total_credits_gifted = $this->analytics->countGiftedCredits();
            $total_credits_unspent = ((int)$total_credits_purchased['total'] + (int)$total_credits_gifted['total']) - (int)$total_credits_spent['total'];

            echo json_encode(array(
                'success' => true,
                'message' => 'Successfully counted the data for the chosen analytic.',
                'context' => 'Everything was fine',
                'total_credits_gifted' => (int)$total_credits_gifted['total'],
                'total_credits_purchased' => (int)$total_credits_purchased['total'],
                'total_credits_spent' => (int)$total_credits_spent['total'],
                'total_credits_unspent' => (int)$total_credits_unspent,
            ));
        }
    }

    public function countForAnalyticsType() {
        $authenticated = $this->authenticateCall();
        if($authenticated) {
            $count = $this->analytics->countForAnalyticsType();
            if($count) {
                echo json_encode(array(
                    'success' => true,
                    'message' => 'Successfully counted the data for the chosen analytic.',
                    'context' => 'Everything was fine',
                    'count' => $count
                ));
            } else {
                echo json_encode(array(
                    'success' => true,
                    'message' => 'Successfully counted the data for the chosen analytic.',
                    'context' => 'Everything was fine',
                    'count' => $count
                ));
            }
        }
    }
    public function displayDownloadLink() {
        $params_array = $this->input->post();
        $zipped = $this->csv->convertToZip($params_array['filename']);
        if($zipped) {
            echo json_encode(array(
                'success' => true,
                'message' => 'Successfully zipped the data. ',
                'url' => 'https://api-taw.pixelbeard.co/TAW_Analytics.zip',
                'context' => 'Everything was fine',
            ));
        } else {
            echo json_encode(array(
                'success' => false,
                'message' => 'There was a problem zipping the data.',
                'context' => 'Everything was NOT fine',
            ));
        }
    }

	public function exportCSVUsingParams() {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$exported = $this->csv->exportCSVUsingParams();
			if($exported['success']) {
				echo json_encode(array(
					'success' => true,
					'message' => 'Successfully exported the data. ',
					'filename' => $exported['filename'],
					'context' => 'Everything was fine',
				));
			} else {
				echo json_encode(array(
					'success' => false,
					'message' => 'There was a problem exporting the data.',
					'context' => 'Everything was NOT fine',
				));
			}
		}
	}

	public function sendNewBespokeNotificationToUsers() {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$notifications = $this->notifications->sendNewBespokeNotificationToUsers();
			if($notifications) {
				echo json_encode(array(
					'success' => true,
					'message' => 'Successfully sent the notification.',
					'context' => 'Everything was fine',
				));
			} else {
				echo json_encode(array(
					'success' => false,
					'message' => 'Failed to send the notification.',
					'context' => 'Everything was NOT fine',
				));
			}
		}
	}

	public function getSentNotifications() {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$notifications = $this->notifications->getSentNotifications();
			if($notifications) {
				echo json_encode(array(
					'success' => true,
					'message' => 'Successfully grabbed the notifications.',
					'context' => 'Everything was fine',
					'notifications' => $notifications
				));
			} else {
				echo json_encode(array(
					'success' => false,
					'message' => 'Failed to grab the notifications.',
					'context' => 'Everything was NOT fine',
					'notifications' => $notifications
				));
			}
		}
	}

	public function getAnalytics($page,$limit = 50) {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$analytics = $this->analytics->getActionsPaginated($page,$limit);
            $count = $this->analytics->analytics_count();
            $count = $count['id'];
//            $count = 56000000000;
			$pages = ceil($count / $limit);
			if ($analytics) {
				echo json_encode(array(
					'success' => true,
					'message' => 'Successfully grabbed analytics',
					'total' => $count,
					'pages' => $pages,
					'data' => $analytics
				));
			} else {
				echo json_encode(array('success' => false, 'message' => 'Failed to grab analytics', 'data' => ''));
			}
		}
	}

	public function getAnalyticsTypes() {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$analytics_types = $this->analytics->getAnalyticsTypes();
			if ($analytics_types) {
				echo json_encode(array(
					'success' => true,
					'message' => 'Successfully grabbed analytics types',
					'data' => $analytics_types
				));
			} else {
				echo json_encode(array('success' => false, 'message' => 'Failed to grab analytics types', 'data' => ''));
			}
		}
	}

	public function getAnalyticsForType($page,$limit = 50,$type) {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$analytics = $this->analytics->getActionsByTypePaginated($page,$limit,$type);
			$count = $this->analytics->analytics_count_for_type($type);
			$pages = ceil($count / $limit);
			if ($analytics) {
				echo json_encode(array(
					'success' => true,
					'message' => 'Successfully grabbed '.$type.' analytics',
					'total' => $count,
					'pages' => $pages,
					'data' => $analytics
				));
			} else {
				echo json_encode(array('success' => false, 'message' => 'Failed to grab analytics', 'data' => ''));
			}
		}
	}

	public function getAnalyticsForUser($page,$limit = 50,$user) {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$analytics = $this->analytics->getAnalyticsForUser($page,$limit,$user);
			$count = $this->analytics->analytics_count_for_user($user);
			$pages = ceil($count / $limit);
			if ($analytics) {
				echo json_encode(array(
					'success' => true,
					'message' => 'Successfully grabbed '.$user.' analytics',
					'total' => $count,
					'pages' => $pages,
					'data' => $analytics
				));
			} else {
				echo json_encode(array('success' => false, 'message' => 'Failed to grab analytics', 'data' => ''));
			}
		}
	}

	// Datatable Analytics
	public function analytics() {
		$columns = array(
			0 =>'id',
			1 =>'date',
			2=> 'partner_id',
			3=> 'type',
			4=> 'variable',
			5=> 'user_id',
			7=> 'id',
		);
		$limit = $this->input->post('length');
		$start = $this->input->post('start');
		$order = $columns[$this->input->post('order')[0]['column']];
		$dir = $this->input->post('order')[0]['dir'];
		$totalData = $this->analytics->analytics_count();
		$totalFiltered = $totalData;
		if(empty($this->input->post('search')['value'])) {
			$posts = $this->analytics->datatables_allanalytics($limit,$start,$order,$dir);
		} else {
			$search = $this->input->post('search')['value'];
			$posts =  $this->analytics->datatables_analytics_search($limit,$start,$search,$order,$dir);
			$totalFiltered = $this->analytics->datatables_analytics_search_count($search);
		}
		$data = array();
		if(!empty($posts)) {
			foreach ($posts as $post) {
				$nestedData['id'] = $post->id;
				$nestedData['date'] = $post->date;
				$nestedData['partner_id'] = $post->partner_id;
				$nestedData['type'] = $post->type;
				$nestedData['variable'] = $post->variable;
				$nestedData['user_id'] = $post->user_id;
				$data[] = $nestedData;
			}
		}
		$json_data = array(
					"draw"            => intval($this->input->post('draw')),
					"recordsTotal"    => intval($totalData),
					"recordsFiltered" => intval($totalFiltered),
					"data"            => $data
					);
		echo json_encode($json_data);
	}
	// Datatable Analytics

	public function sendNewPodcastNotificationToUsers() {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$sent = $this->notifications->sendNewPodcastNotificationToUsers();
			if($sent) {
				echo json_encode(array('success' => true, 'message' => 'Successfully sent notifications', 'list' => $sent));
			} else {
				echo json_encode(array('success' => false, 'message' => 'Failed to send notifications'));
			}
		}
	}

	public function authenticateCall() {
		$headers = $this->input->request_headers();
		if ($this->checkUserToken($headers)) {
			$user = $this->users->getFullUserByTokenFrontend($headers['User-Api-Token']);
			$auth_level = $this->checkUsersAuthLevel($user);
			if($auth_level != 9) {
				echo json_encode(array('success' => false, 'message' => 'This resource is only allocated to administrators.'));
			} else {
				return $auth_level;
			}
		}
	}

	/* ********************************************************** */
	/* ADDITIONAL USER SERVICES ******************************************** */
	/* ********************************************************** */

	public function updateUserFromAMemberWebhook() {
		$results = $this->users->updateUserFromAMemberWebhook();
		if($results) {
			echo json_encode(array('success' => true, 'message' => 'Found results', 'users' => $results));
		} else {
			echo json_encode(array('success' => false, 'message' => 'Could not find results', 'users' => $results));
		}
	}

	public function getSubscribersForNotificationType($type) {
		$results = $this->notifications->debugGetAllUsersSubscribedToPodcastNotifications($type);
		if($results) {
			echo json_encode(array('success' => true, 'message' => 'Found results', 'users' => $results));
		} else {
			echo json_encode(array('success' => false, 'message' => 'Could not find results', 'users' => $results));
		}
	}

	public function adminSearchUsers() {
		$keywords = $this->input->post('keywords');
		$results = $this->users->searchUsersByKeywords($keywords);
		if($results) {
			echo json_encode(array('success' => true, 'message' => 'Found results', 'users' => $results));
		} else {
			echo json_encode(array('success' => true, 'message' => 'Could not find results', 'users' => $results));
		}
	}

	public function editUser($user_id) {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$user = $this->users->adminEditUser($user_id);
			if($user) {
				echo json_encode(array('success' => true, 'message' => 'Successfully edited user', 'user' => $user));
			} else {
				echo json_encode(array('success' => false, 'message' => 'Failed to edit user'));
			}
		}
	}

	public function unlinkDeviceByID() {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$unlinked = $this->users->unlinkDeviceForUser();
			if($unlinked) {
				echo json_encode(array(
					'success' => true,
					'message' => 'Successfully unlinked the device for user.',
					'context' => 'Everything was fine',
				));
			} else {
				echo json_encode(array(
					'success' => false,
					'message' => 'Failed to unlink the device for user.',
					'context' => 'This device id wasnt found',
				));
			}
		}
	}


	public function getUser($user_id) {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$user = $this->users->adminGetUser($user_id);
			if($user) {
				echo json_encode(array('success' => true, 'message' => 'Successfully retrieved user', 'user' => $user));
			} else {
				echo json_encode(array('success' => false, 'message' => 'Failed to retrieve user'));
			}
		}
	}

	public function checkUserToken($headers) {
		if (isset($headers['User-Api-Token'])) {
			$api_token = $headers['User-Api-Token'];
			$valid = $this->users->isTokenValid($api_token);
			if ($valid) {
				return $valid;
			} else {
				echo json_encode(array('success' => false, 'message' => 'Invalid Token'));
			}
		} else {
			echo json_encode(array('success' => false, 'message' => 'No token sent in header'));
		}
	}

	function checkUsersAuthLevel($user) {
		return $user['auth_level'];
	}

	function getUsersPaginated($page,$auth) {
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$count = $this->users->countUsers($auth);
			$pages = ceil($count / 25);
			$users = $this->users->adminGetUsersPaginated($page,$auth);
			echo json_encode(array('success' => true, 'message' => 'Successfully retrieved all users', 'total' => $count, 'pages' => $pages, 'users' => $users));
		}
	}

	function updateFreeSubscriptionDuration(){
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$duration = $this->input->post('duration');
			if(is_numeric($duration)) {
				$duration = $this->input->post('duration');
			}
			else {
				echo json_encode(array('success' => false, 'message' => 'expected parameter duration'));
				return;
			}

			if($this->input->post('type')) {
				$type = $this->input->post('type');
			}
			else {
				echo json_encode(array('success' => false, 'message' => 'expected parameter type'));
				return;
			}
			
			$updated = $this->subscriptions->updateFreeSubscription($duration,$type);
			if($updated) {
				$subscription = $this->subscriptions->getFreeSubscription();
				echo json_encode(array('success' => true, 'message' => 'Subscription successfully updated', 'free_subscription' => $subscription));
			} else {
				echo json_encode(array('success' => false, 'message' => 'Failed to update subscription'));
			}
		}
	}

	function getFreeSubscriptionDuration(){
		$authenticated = $this->authenticateCall();
		if($authenticated) {
			$subscription = $this->subscriptions->getFreeSubscription();
			$free_subscription_duration = $subscription[0]->plan_duration;
			if($subscription)
			{
				echo json_encode(array('success' => true, 'message' => 'Free subscription duration', 'duration' => $free_subscription_duration));
			}
			else
			{
				echo json_encode(array('success' => false, 'message' => 'Failed to get subscription duration'));
			}
		}
	}
}
