<?php

class AddressApi extends Api
{
    public $apiName = 'address';
    const SEARCH_RADIUS = 100000; // 100km
    const SEARCH_RESULTS = 3;

    public function indexAction()
    {
        //syslog(LOG_WARNING,'AddressApi::indexAction()');
        $country = trim($this->requestParams["country"] ?? "");
        $address = trim($this->requestParams["address"] ?? "");
        $location = $this->requestParams['location'] ?? [];
        $member_id = $this->requestParams["member_id"] ?? 0;
        if ($country!='US') $country = 'SG';
        //error_log('country='.$country.', member_id='.$member_id);
        
        if (strlen($address)>2) {
            $db = new Db();

            // DEBUG
            $country = Geocode::mockGPSCountry($db->getConnect(), $member_id, $country, 'default');

            $results = Address::search($db->getConnect(), $country, $address);
            //error_log('results='.count($results).", strlen=".strlen($address));
            if ((!is_array($results) || count($results)<1) && strlen($address)>7) {
                $results = AddressApi::searchGooglePlaces($db, $address, $country, $location, $member_id);
            }
            if(is_array($results) && count($results)>0){
                return $this->response(
                    array(
                        'country' => $country,
                        'address' => $address,
                        'count' => count($results),
                        'addresses' => $results
                    ), 200);
            }
        }  
        return $this->response(
            array(
                'error' => 'Data not found'
            ), 404);
    }

    /**
     * Method GET
     * Get single record (by id)
     * http://DOMAIN/address/1
     * @return string
     */
    public function viewAction()
    {
        //id must be the first parameter after /address/x
        $id = array_shift($this->requestUri);

        if($id && (int)$id>0){
            $db = new Db();
            $address = Address::getAddressById($db->getConnect(), (int)$id);
            if(is_array($address) && count($address)>0){
                return $this->response($address, 200);
            }
        }
        return $this->response(
            array(
                'error'=> 'Data not found'
            ), 404);
    }

    public function createAction()
    {
        $country = trim($this->requestParams["country"] ?? "");
        $address = trim($this->requestParams["address"] ?? "");
        $member_id = (int)($this->requestParams["member_id"] ?? 0);
        $location = $this->requestParams['location'] ?? [];
        $autocomplete = (int)($this->requestParams["autocomplete"] ?? 0);

        if ($country!='US') $country = 'SG';
        if (strlen($address)>2) {
            $db = new Db();
            $benchmarks['function'] = 'createaddress';
            Utilities::startBenchmark($benchmarks);
            // DEBUG
            $country = Geocode::mockGPSCountry($db->getConnect(), $member_id, $country, 'default');

            $recentTrips = [];
            $favourites = [];
            if ($autocomplete) {
              $results = Address::searchInView($db->getConnect(), $country, $address);
            } else {
              if ($member_id>0) {
                $recentTrips = Address::recentTrips($db->getConnect(), $member_id, $country, $address);
                $favourites = Address::favourites($db->getConnect(), $member_id, $country, $address);
              }
              $results = Address::search($db->getConnect(), $country, $address);
            }
            // if ((!is_array($results) || count($results)<1) && strlen($address)>7) {
            if ((!is_array($results) || count($results)<3) && strlen($address)>7) {
                if (!is_array($results)) $results = [];
                $results = array_merge(
                    $results,
                    AddressApi::searchGooglePlaces($db, $address, $country, $location, $member_id)
                );
            }
            Utilities::finishBenchmark($benchmarks);
            if ((is_array($results) && count($results)>0) 
             || (is_array($recentTrips) && count($recentTrips)>0)
             || (is_array($favourites) && count($favourites)>0)) {
                return $this->response(
                    array(
                        'country' => $country,
                        'address' => $address,
                        'count' => is_array($results) ? count($results) : 0,
                        'addresses' => $results,
                        'recent' => $recentTrips,
                        'favourites' => $favourites,
                        'location' => $location
                    ), 200);
            }
        }  
        return $this->response(
            array(
                "error" => "Data not found"
            ), 404);
    }

    public function updateAction()
    {
        return $this->response(
            array(
                "error" => "Update error"
            ), 400);
    }

    public function deleteAction()
    {
        return $this->response(
            array(
                "error" => "Delete error"
            ), 500);
    }

    public function searchGooglePlaces($db, $address, $country, $location, $member_id) {
        syslog(LOG_WARNING,"AddressApi::searchGooglePlaces(\$db, $address, $country, \$location, $member_id)");
        global $savvyext;
        $result = [];

        $has_location = true;    
        if (!is_array($location) || count($location)!=2 
        || !array_key_exists('lat',$location) || !array_key_exists('lng',$location)
        || ($location['lat']==0 && $location['lng']==0)) {
            $has_location = false;
        }
        syslog(LOG_WARNING,"has_location=".($has_location?"TRUE":"FALSE"));
        require_once('../common/GooglePlaces.php');

        $key = $savvyext->cfgReadChar('google.api_key');

        $places = new GooglePlaces($key);

        if ($has_location) {
            syslog(LOG_WARNING,"location => (".$location['lat'].",".$location['lng'].") => ".AddressApi::SEARCH_RADIUS);
            $places->location = [$location['lat'], $location['lng']]; //array(33.9212128,-84.4787968);
            $places->radius   = AddressApi::SEARCH_RADIUS; // 2600 Bentley
        } else {
            syslog(LOG_WARNING,"No location!");
        }
        $places->types = 'geocode'; // 'address';
        $places->input = $address;
        $benchmarks = [];
        $benchmarks['function'] = 'google places';
        Utilities::startBenchmark($benchmarks);
        $results       = $places->autoComplete();
        Utilities::finishBenchmark($benchmarks);
        syslog(LOG_WARNING,json_encode($results));
        if (is_array($results) && array_key_exists('predictions',$results) && count($results['predictions'])>0) {
            $predictions = [];    
            foreach ($results['predictions'] as $item) {
                if (in_array("street_address",$item["types"]) || in_array("premise",$item["types"])) {
                    $predictions[] = $item["description"]; // 2600 Bentley Road Southeast, Marietta, GA, USA
                    $result[]['address'] = $item["description"]; 
                    if (count($result)>=AddressApi::SEARCH_RESULTS) break;
                }
            }
            /*$i = 0;
            foreach ($predictions as $address) {
                list($res, $err) = GeocodeApi::geocode($db, $address, $country);
                if (is_array($res) && array_key_exists('id',$res) && $res['id']>0) {
                    $result[] = $res;
                    $i++;
                } else {
                    syslog(LOG_WARNING,$err!=""?$err:'Geocoding error!');
                }
                if ($i>=AddressApi::SEARCH_RESULTS) break;
            }*/
        }
        return $result;
    }
}
