<?php

class HourlyAveragesApi extends Api {
	public $apiName = 'hourlyaverages';

	public function __construct($requestUri, $encryption=true) {
		$encryption = false; // We do not need encryption for this class
		parent::__construct($requestUri, $encryption);
		//$this->encryption = $encryption;
	}

	/**
	 * @OA\Get(
	 *   path="/SAVVY/geofencearea/api/addresstoarea?address_id={address_id}",
	 *   security={{"token": {}}},
	 *   summary="Geocode address id to a geofence area",
	 *   @OA\Response(
	 *     response="200",
	 *     description="area list address belongs to",
	 *     @OA\JsonContent(
	 *       type="object"
	 *     )
	 *   )
	 * )
	 */
	public function indexAction() {
		$message = 'No hourly data found';

		$from_address = $this->requestParams['from_address'] ?? '';
		$to_address = $this->requestParams['to_address'] ?? '';
		$country = $this->requestParams['country'] ?? '';
		$city = $this->requestParams['city'] ?? 0;
    $member_id = $this->requestParams['member_id'] ?? 0;
    $from_lat = $this->requestParams['from_lat'] ?? '';
    $from_lng = $this->requestParams['from_lng'] ?? '';
    $to_lat = $this->requestParams['to_lat'] ?? '';
    $to_lng = $this->requestParams['to_lng'] ?? '';
    $from_postal_code = $this->requestParams['from_postal_code'] ?? null;
    $to_postal_code = $this->requestParams['to_postal_code'] ?? null;

		try {

			if ($from_address==="") {
				throw new Exception("Invalid from address");
			}
      if ($to_address==="") {
				throw new Exception("Invalid to address");
			}
			if ($city<1) {
				throw new Exception("Invalid city");
			}
			if (!in_array(strtoupper($country), ['SG','US']) ) { // Singapore and USA only for now
				throw new Exception("Invalid country");
      }

			// Get city info by ID

      $db = new Db();
      $cityInfo = HourlyAverages::getCityInfo($db->getConnect(), $city);
      if (count($cityInfo) == 0) {
        throw new Exception("Couldn't get information for city with id=${city}");
      }

      $timeZoneId = $cityInfo['timezone'];
      $cityName = $cityInfo['city'];


			// Step 1: geocode the addresses
      if ($from_lat && $from_lng) {
        
        $fAddress = [
          'address' => $from_address,
          'geocode' => [
            'message' => '',
            'latitude' => $from_lat,
            'longitude' => $from_lng,
            'address' => $from_address,
            'postal' => $from_postal_code,
            'timeZoneId' => $timeZoneId,
            'city' => $cityName,
            'city_lat' => $from_lat,
            'city_lng' => $from_lng,
            'country' => $country,
            'id' => null
          ],
          'error' => null
        ];

      } else {

        list($fAddress, $err) = $this->geocode($from_address,$country,(int)$member_id);
        if (!is_array($fAddress) || !array_key_exists('geocode',$fAddress) || !is_array($fAddress['geocode']) 
        || !array_key_exists('id',$fAddress['geocode']) || $fAddress['geocode']['id']<1) {
          throw new Exception("Failed to geocode from address".json_encode($fAddress));
        }

        $fAddress['geocode']['longitude'] = $fAddress['geocode']['lng'];
        $fAddress['geocode']['latitude'] = $fAddress['geocode']['lat'];

      }
      if ($to_lat && $to_lng) {

        $tAddress = [
          'address' => $to_address,
          'geocode' => [
            'message' => '',
            'latitude' => $to_lat,
            'longitude' => $to_lng,
            'address' => $to_address,
            'postal' => $to_postal_code,
            'timeZoneId' => $timeZoneId,
            'city' => $cityName,
            'city_lat' => $to_lat,
            'city_lng' => $to_lng,
            'country' => $country,
            'id' => null
          ],
          'error' => null
        ];

      } else {

        list($tAddress, $err) = $this->geocode($to_address,$country,(int)$member_id);
        if (!is_array($tAddress) || !array_key_exists('geocode',$tAddress) || !is_array($tAddress['geocode'])
        || !array_key_exists('id',$tAddress['geocode']) || $tAddress['geocode']['id']<1) {
          throw new Exception("Failed to geocode to address");
        }

        $tAddress['geocode']['longitude'] = $tAddress['geocode']['lng'];
        $tAddress['geocode']['latitude'] = $tAddress['geocode']['lat'];

      }

			list($res, $err) = HourlyAverages::get( $db->getConnect(), $fAddress['geocode'], $tAddress['geocode'], $city, $country );
			if (!is_array($res) || count($res)<1) {
				throw new Exception($err!==""?$err:"Failed to get hourly averages");
			}
			$result = [
				'city' => $city,
				'country' => $country,
				'member_id' => $member_id,
				'from_address' => $fAddress,
				'to_address' => $tAddress,
				'data' => $res
			];
			return $this->response(
				[
					"hourlyaverages" => $result,
					"error" => $err
				], 200 );

		} catch (Exception $e) {
			$message = $e->getMessage();
		}		
		return $this->response(
            [
				"hourlyaverages" => NULL, 
                "error" => $message
			], 404);
	}

	public function viewAction() {

	}

	public function createAction() {

	}

	public function updateAction() {

	}

	public function deleteAction() {

	}

	protected function geocode($address, $country, $member_id=0) {
		global $httpAuthToken, $savvyext;

		$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
		$encryptionKey = $savvyext->cfgReadChar('encryption.key');
		$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
		$baseURL = $savvyext->cfgReadChar('system.api_url');

		$in = [
			'address' => $address,
			'member_id' => $member_id,
			'country' => $country
		];
		$data = http_build_query($in);
		
		$url = $baseURL . "/trips/api/geocode/?".$data;
		
		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_VERBOSE, false);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array(
			'Content-Type: application/json',
			'Authorization: Server-Token ' . $httpAuthToken)
		);
		
		$body = curl_exec($ch);

		$result = json_decode($body,true);
		
		$payload = openssl_decrypt(
			hex2bin(
				$result['payload']
			),
			$encryptionAlg,
			$encryptionKey,
			OPENSSL_RAW_DATA,
			$encryptionIV
		);
		  
		return [json_decode($payload,true),$body];
	}

}
