<?php

/**
 * Register all api actions
 *
 * @link       https://revivedesignstudios.com
 * @since      1.0.0
 *
 * @package    Rds_Bt50_Scorecard
 * @subpackage Rds_Bt50_Scorecard/includes
 */

/**
 * Register all api actions
 *
 * @package    Rds_Bt50_Scorecard
 * @subpackage Rds_scBt50_Scorecard/includes
 * @author     Revive Design Studios <connect@revivedesignstudios.com>
 */
class Rds_Bt50_Scorecard_Api {
	/**
	* The ID of this plugin.
	*
	* @since    1.0.0
	* @access   private
	* @var      string    $plugin_name    The ID of this plugin.
	*/
	private $plugin_name;

	/**
	* The version of this plugin.
	*
	* @since    1.0.0
	* @access   private
	* @var      string    $version    The current version of this plugin.
	*/
	private $version;

	private $wysiwygAdminFields = array(
		'score_subtitle',
		'score_info',
		'sidebar_promo_description',
		'promo_legislator_page',
	);
	private $ksesAllowedHtml = array(
			'a' => array(
				'href' => array(),
				'title' => array()
			),
			'img' => array (
				'src' => array(),
				'alt' => array()
			),
			'br' => array(),
			'em' => array(),
			'strong' => array(),
			'p' => array(),
			'i' => array(),
			'em' => array(),
			'h1' => array(),
			'h2' => array(),
			'h3' => array(),
			'h4' => array(),
			'h5' => array(),
			'h6' => array(),
			'li' => array(),
			'ul' => array(),
	);

	/**
	* Initialize the collections used to maintain the actions and filters.
	*
	* @since    1.0.0
	* @param      string    $plugin_name       The name of the plugin.
	* @param      string    $version    The version of this plugin.
	* @param      Bt50DataClient    $dataClient    The data client.
	*/
	public function __construct( $plugin_name, $version, $dataClient ) {
		$this->plugin_name = $plugin_name;
		$this->version = $version;
		$this->dataClient = $dataClient;
	}

	/**
	* Register rest routes for the plugin.
	*
	* @since    1.0.0
	*/
	public function register_rest_routes() {
		// TODO: add permissions callback
		$getLegislatorsRouteConfig = array (
			'methods' => WP_REST_Server::READABLE,
			'callback' => array( $this->dataClient,  'getLegislators' ),
			'args' => array('address'),
		);

		$getBillsRouteConfig = array (
			'methods' => WP_REST_Server::READABLE,
			'callback' => array( $this->dataClient,  'getBills' ),
			'args' => array(),
		);

		$getDetailRouteConfig = array (
			'methods' => WP_REST_Server::READABLE,
			'callback' => array( $this->dataClient,  'scorecardLegislatorDetail' ),
			'args' => array('legislatorId'),
		);

		$getStylesRouteConfig = array (
			'methods' => WP_REST_Server::READABLE,
			'callback' => array( $this, 'getScorecardConfiguration'),
			'args' => array(),
		);

		$getAdminSettings = array (
			'methods' => WP_REST_Server::READABLE,
			'callback'            => array( $this, 'get_admin_settings' ),
			'permission_callback' => array( $this, 'get_admin_settings_permissions_check' ),
			'args' => array(),
		);

		$updateAdminSettings = array (
			'methods' => WP_REST_Server::EDITABLE,
			'callback'            => array( $this, 'update_admin_settings' ),
			'permission_callback' => array( $this, 'update_admin_settings_permissions_check' ),
			'args' => array(),
		);

		/* GET LEGISLATORS
		*  Get list of all legislators associated with a scorecard_id
		*  curl http://localhost:8083/wp-json/rds-bt50-scorecard/v1/legislators | prettyjson
		*  Optional Search Param to query legislators by address
		*  curl http://localhost:8083/wp-json/rds-bt50-scorecard/v1/legislators/?address=1050+6th+Ave,+Des+Moines,+IA | prettyjson
		*/
		register_rest_route( $this->plugin_name . '/v1', '/legislators', $getLegislatorsRouteConfig );

		/* GET BILLS
		*  Get list of bills associated with a scorecard
		*  curl http://localhost:8083/wp-json/rds-bt50-scorecard/v1/bills | prettyjson
		*/
		register_rest_route( $this->plugin_name . '/v1', '/bills', $getBillsRouteConfig );

		/* GET LEGISLATOR DETAIL
		*  Get the Legislators scorecard
		*  curl http://localhost:8083/wp-json/rds-bt50-scorecard/v1/legislators/detail | prettyjson
		*/
		register_rest_route( $this->plugin_name . '/v1', '/legislators/detail', $getDetailRouteConfig );

		/*
		* POST configuration options
		* GET configuration options
		*/
		register_rest_route( $this->plugin_name . '/v1', '/settings', array ( $updateAdminSettings, $getAdminSettings ) );

		/* GET PLUGIN CUSTOM STYLES
		*  Get the Legislators scorecard custom styles
		*  curl http://localhost:8083/wp-json/rds-bt50-scorecard/v1/styles | prettyjson
		*/
		register_rest_route( $this->plugin_name . '/v1', '/styles', $getStylesRouteConfig ); // todo: rename to something like '/app-config'
	}

	public function get_admin_settings($request) {
		$nonce = $request->get_header('X-WP-Nonce');
		if (check_ajax_referer( 'wp_rest', $nonce, false )) {
			return new WP_REST_Response( 'Fobidden', 403 );
		};
		$allOpts = get_option('rds_bt50');
		$responseData = $this->get_admin_settings_defaults();
		$responseMeta = array();
		foreach (Rds_Bt50_Scorecard_Validations::$apiParamsWhitelist as $key) {
			if (array_key_exists($key, $allOpts)) {
				$responseData[$key] = $allOpts[$key];
			}
		}

		$cats = $this->getCategoryOptions();
		$responseMeta = array ( 'wp_categories' => $cats );

		return new WP_REST_Response(
			array( 'data' => $responseData, 'meta' => $responseMeta)
		);
	}

	public function getCategoryOptions() {
		$cats = get_categories( array('hide_empty' => false));
		$formattedCats = array();
		// NOTE: array_map returns and array with keys, which wp rest api turns to objects (whereas we want an array)
		foreach ($cats as $cat) {
			array_push($formattedCats, array (
				'id' => $cat->term_id,
				'name' => $cat->name,
				'parent' => $cat->parent,
			));
		}
		return $formattedCats;
	}

	public function getRecentPosts($categoryIds) {
		if (sizeOf($categoryIds) == 0) { return array(); }
		$recentPostsArgs = array (
			'posts_per_page' => -1,
			'cat' => implode(',', $categoryIds),
		);
		$posts = get_posts( $recentPostsArgs );
		$recentPosts = array_map(function($post){
			return array (
				'id' => $post->ID,
				'url' => get_permalink($post),
				'post_name' => $post->post_name,
				'post_title' => get_the_title($post),
			);
		}, $posts);
		return $recentPosts;
	}

	public function get_admin_settings_defaults() {
		// There must be a default key entry for all keys to be used from '$allOpts'
		// These should all be listed in $apiParamsWhitelist as well
		return array(
			'display_promo_sidebar' => false,
			'display_recent_wp_post' => false,
			'display_recent_bt50_bills' => true,
			'enable_legislator_pagination' => true,
			'force_https_urls' => false,
			'legislator_page_name_color' => '#FFFFFF',
			'promo_legislator_page' => '',
			'rds_bt50_scorerange_splits' => array( 0 ),
			'rds_bt50_scorerange_colors' => array ( '#a0111d', '#0a884a'),
			'recent_wp_post_categories' => array(),
			'score_title_color' => '#FFFFFF',
			'score_primary_color' => '#152D4E',
			'score_secondary_color' => '#FFAF54',
			'score_subtitle' => 'Our goal is to help organizations like yours make state legislation transparent and readily accessible. View all representatives below or enter your address to find your specific representatives.',
			'score_info' => 'This section allows you to briefly describe your scoring methodology, values, and goals for your visitors.',
			'sidebar_promo_title' => '',
			'sidebar_promo_description' => '',
			'score_type_to_display' => 'totalscore'
			// 'show_presence_score' => ',
		);
	}

	public function getScorecardConfiguration() {
		$allOpts = get_option('rds_bt50');
		$scorecardSettings = $this->get_admin_settings_defaults();
		foreach ($scorecardSettings as $key => $value) {
			if (array_key_exists($key, $allOpts)) {
				$scorecardSettings[$key] = $allOpts[$key];
			}
		}

		$categoryIds = $scorecardSettings['recent_wp_post_categories'];
		$recentPosts = $this->getRecentPosts($categoryIds);

		$attachmentId = get_option('score_header_img');
		$imageUrl = wp_get_attachment_image_src($attachmentId, 'full');
		$response = array(
			'display_recent_wp_post' => $scorecardSettings['display_recent_wp_post'],
			'display_recent_bt50_bills' => $scorecardSettings['display_recent_bt50_bills'],
			'display_promo_sidebar' => $scorecardSettings['display_promo_sidebar'],
			'enable_legislator_pagination' => $scorecardSettings['enable_legislator_pagination'],
			'primary' => $scorecardSettings['score_primary_color'],
			'secondary' => $scorecardSettings['score_secondary_color'],
			'title' => $scorecardSettings['score_title_color'],
			'legislator_page_name_color' => $scorecardSettings['legislator_page_name_color'],
			'header' => $imageUrl[0],
			'header_txt' => get_option('score_header'),
			'header_subtxt' => $scorecardSettings['score_subtitle'],
			'sidebar_promo_title' => $scorecardSettings['sidebar_promo_title'],
			'sidebar_promo_description' => $scorecardSettings['sidebar_promo_description'],
			'promo_legislator_page' => $scorecardSettings['promo_legislator_page'],
			'force_https_urls' => $scorecardSettings['force_https_urls'],
			'info' => $scorecardSettings['score_info'],
			'loggedIn' => get_option('score_membership'),
			'rangeSplits' => $scorecardSettings['rds_bt50_scorerange_splits'],
			'rangeColors' => $scorecardSettings['rds_bt50_scorerange_colors'],
			'recentActivity' => $recentPosts,
			'score_type_to_display' => $scorecardSettings['score_type_to_display'],
		);
		return $response;
	}

	public function get_admin_settings_permissions_check() {
		return current_user_can( 'edit_others_posts' );
	}

	public function update_admin_settings($request) {
		$nonce = $request->get_header('X-WP-Nonce');
		if (check_ajax_referer( 'wp_rest', $nonce, false )) {
			return new WP_REST_Response( 'Fobidden', 403 );
		};
		$params = $request->get_params();

		// VALIDATION
		$validationErrors = Rds_Bt50_Scorecard_Validations::getAdminParamsValidationErrors($params);
		if (sizeOf($validationErrors) > 0) {
			return new WP_REST_Response( $validationErrors, 400 );
		}

		// UPDATE
		$allOpts = get_option('rds_bt50');
		$updatedValues = array ();
		foreach ($params as $key => $value) {
			if (array_search($key, Rds_Bt50_Scorecard_Validations::$apiParamsWhitelist) === false) {
				error_log('BT50 scorecard: '. $key . ' is not a valid api param');
				continue;
			}

			if (array_search($key, $this->wysiwygAdminFields) === true) { // is whitelisted as wysiwyg field
				$sanitizedValue = wp_kses($value, $this->ksesAllowedHtml);
				$allOpts[$key] = $sanitizedValue;
				$updatedValues[$key] = $sanitizedValue;
			} else {
				$allOpts[$key] = $value;
				$updatedValues[$key] = $value;
			}
		}
		update_option('rds_bt50', $allOpts);
		return new WP_REST_Response( $updatedValues );
	}

	public function update_admin_settings_permissions_check() {
		return current_user_can( 'edit_others_posts' );
	}

}
