<?php

// Joins API data and processes
Class Bt50DataClient {
	public function __construct($bt50Client, $openstatesClient) {
		$this->bt50Client = $bt50Client;
		$this->openstatesClient = $openstatesClient;
		add_filter(
			'bt50_scorecard_geolocation_api_key',
			array( $this, 'get_geolocation_api_key' ),
			0
		);
		// $this->cacheProvider = $cacheProvider;
	}

	public function bt50ConnectionValid() {
		return $this->bt50Client->connectionValid();
	}

	public function scorecard() {
		$response = $this->scorecards();
		$scorecardId = get_option('score_id');
		$result = $response[0];

		for($i = 0; $i < sizeof($response); $i++){
			if($response[$i]['ScorecardID'] == $scorecardId){
				$result = $response[$i];
			}
		}
		return $result;
	}

	public function scorecards() {
		$response = $this->bt50Client->scorecards();
		return is_wp_error($response) ? $response : $response['Scorecards'];
	}

	public function getBills() {
		$scorecard_id = get_option('score_id');
		$response = $this->bt50Client->bills($scorecard_id);
		return $response;
	}

	function combineLegislatorData($bt50Legislator, $openstatesLegislator) {
		preg_match(Rds_Bt50_Scorecard_Dictionary_Generator::$bt50DistrictRegex, $bt50Legislator['District'], $matches);
		$state = strtolower($matches['stateCode']);
		$bt50Data = array(
			'id' => $bt50Legislator['LegislatorID'],
			'first_name' => $bt50Legislator['FirstName'],
			'last_name' => $bt50Legislator['LastName'],
			'score' => $bt50Legislator['TotalScore'],
			'possible_score' => $bt50Legislator['PossibleScore'],
			'vote_index' => $bt50Legislator['VoteIndex'],
			'party' => $bt50Legislator['Party'],
			'district' => $bt50Legislator['District'],
			'chamber' => $bt50Legislator['Chamber'],
			'state' => $state
		);
		if ($openstatesLegislator) {
			$openstatesData = array(
				'state' => $openstatesLegislator['state'],
				'photo' => $openstatesLegislator['photo_url'],
				'offices' => $openstatesLegislator['offices']
			);
		} else {
			$openstatesData = array(
				'photo' => null,
				'offices' => []
			);
		}
		$combinedLegislator = array_merge($bt50Data, $openstatesData);
		return $combinedLegislator;
	}

	public function generateLegislatorJson($bt50Response, $osResponse, $isGeoFilteredOpenstates) {
		$legislatorsList = array();

		$bt50Dictionary =
			Rds_Bt50_Scorecard_Dictionary_Generator::createBt50LegislatorDictionary($bt50Response['Legislators']);
		$osDictionary =
			Rds_Bt50_Scorecard_Dictionary_Generator::generateOsLegislatorDictionary($osResponse);
		$scorecardId = get_option('score_id');
		$presenceSessionId = ($scorecardId == 1700) ? 479 : $this->bt50Client->getCurrentSessionByScorecard($scorecardId);
		$presenceResponse = $this->bt50Client->presence($presenceSessionId);
		$presenceData =
			Rds_Bt50_Scorecard_Dictionary_Generator::generateBt50PresenceDictionary($presenceResponse);
		foreach ($bt50Dictionary as $key => $bt50Legislator) {
			if (!array_key_exists($key, $osDictionary)) {
				if ($isGeoFilteredOpenstates) { continue; }
				error_log("BT50 scorecard: OS legislator not found for key: " . $key);
			}
			$osLegislator = @$osDictionary[$key] ?: null;
			$combinedLegislator = $this->combineLegislatorData($bt50Legislator, $osLegislator);
			$legislatorPresenceData = @$presenceData[$combinedLegislator['id']] ?: null;
			$combinedLegislator['presence_score'] = $legislatorPresenceData ? $legislatorPresenceData['Presence'] : 0.0;
			array_push($legislatorsList, $combinedLegislator);
		}

		$useBlendedScore = get_option('rds_bt50_blendedscore_enabled');
		if ($useBlendedScore) {
			// TODO: modify admin to allow for users to enter secondary scorecard and weights
			$blenderSetttings = array (
				'sponsorshipScorecardId' => 1706,
				'sponsorshipScoreMultiplier' => 3,
				'voteScoreWeight' => 0.5,
				'presenceScoreWeight' => 0.3,
				'sponsorPointsTotal' => 15,
				'maxVoteScoreVotes' => 9,
			);

			$scoreBlender = new Rds_Bt50_Scorecard_Score_Blender($this->bt50Client, $blenderSetttings);
			foreach ($legislatorsList as $key => $value) {
				$legislatorsList[$key]['score'] = $scoreBlender->getBlendedScoreByBt50LegislatorID($value['id']);
			}
		}

		return $legislatorsList;
	}

	public function get_geolocation_api_key($defaultKey) {
		$optionKey = get_option('geolocation_api_key');
		if ($optionKey) {
			return $optionKey;
		}
		return $defaultKey;
	}

	public function getLegislators($args) {
		$scorecard_id = get_option('score_id');
		$bt50Response = $this->bt50Client->scorecardLegislatorList($scorecard_id);

		$scorecard = $this->scorecard();
		$stateCode = $scorecard['StateCode'];

		if ($args['address']) {
			return $this->getGeoFilteredResponse($args['address'], $bt50Response);
		}

		//make the open states api call for the legislators associated with the lat, long and state from the args variable
		$osResponse = $this->openstatesClient->stateSearch($stateCode);
		$response = $this->generateLegislatorJson($bt50Response, $osResponse, false);

		return $response;
	}

	public function getGeoFilteredResponse($address, $bt50Response) {
		$geolocation_api_key = apply_filters(
			'bt50_scorecard_geolocation_api_key',
			'AIzaSyAn9Zb1f9e96oWSwkxbQ7WDVjhPtJ3XQRc'
		);

		$geocoder = new GoogleMapsGeocoder();
		$geocoder->setApiKey($geolocation_api_key);
		$geocoder->setAddress($address);
		$useHttps = true;
		$response = $geocoder->geocode($useHttps);
		$location = $response['results'][0]['geometry']['location'];
		$geo['lat'] = $location['lat'];
		$geo['long'] = $location['lng'];

		$osResponse = $this->openstatesClient->geoSearch($geo);
		$response = $this->generateLegislatorJson($bt50Response, $osResponse, true);
		return $response;
	}

	public function scorecardLegislatorDetail($args) {
		return $this->bt50Client->scorecardLegislatorDetail($args);
	}

}
