<?php

class DestinationsApi extends Api
{
    public $apiName = 'destinations';

    public function indexAction()
    {
        return $this->response(
            array(
                'error' => 'Data not found'
            ), 404);
    }

    /**
     * Method GET
     * Get single record (by id)
     * http://DOMAIN/destinations/1
     * @return string
     */
    public function viewAction()
    {
        return $this->response(
            array(
                'error'=> 'Data not found'
            ), 404);
    }

    public function createAction()
    {
        syslog(LOG_WARNING,'DestinationsApi::createAction()');
        $message = 'We could not find any recent activity in this area';
        $code = 404;
        $time = $this->requestParams['time'] ?? '';
        $location = $this->requestParams['location'] ?? [];
        $country = $this->requestParams['country'] ?? '';
        $member_id = $this->requestParams['member_id'] ?? 0;
        try {
            $db = new Db();

            $country = Geocode::getCountryByGPS($db->getConnect(), $location, $country, Destinations::DEFAULT_COUNTRY);
            syslog(LOG_WARNING,'country='.$country);

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

            $gps_country_code = $country; // Guessed

            if ($country!='US' && $country!='SG') {
                throw new RuntimeException('Trips has not yet launched in your country. You can still track your travel activity and access exclusive deals. Start exploring!',500);
            }
            if ($member_id<1) {
                throw new RuntimeException('Invalid member ID',500);
            }
            if ($time=='' || strtotime($time)<Destinations::TIME_LIMIT) { 
                throw new RuntimeException('Invalid time',500);
            }
            $address = NULL;
            $street_address = "";
            syslog(LOG_WARNING, "location => " . json_encode($location));

            if (is_array($location) && isset($location["lat"]) && isset($location["lng"])) {
                // DEBUG
                list($location["lat"],$location["lng"]) = Geocode::mockGPSLocation(
                    $db->getConnect(), $member_id, $location["lat"], $location["lng"], 'default');
                
                syslog(LOG_WARNING,"lat=".$location["lat"].",lng=".$location["lng"]);
                list($street_address,$err) = GeocodeApi::reverseGeocode($db, $location["lat"], $location["lng"]);
                if ($street_address=="") {
                    list($address,$err) = GeofenceApi::getAnchor($db, $location["lat"], $location["lng"]);
                    if (is_array($address) && array_key_exists("address",$address) && $address["address"]!="") {
                        $street_address = $address["address"];
                    }
                }
                if ($street_address=="") {
                    syslog(LOG_WARNING,'Reverse geocoder failed for ('.$location["lat"].', '.$location["lng"].')');
                    throw new RuntimeException($err?"Geocoder failed: $err":'Cannot geocode your GPS location',500);
                }
                syslog(LOG_WARNING,"street_address=".json_encode($street_address));
                if (!is_array($address) || !array_key_exists("address",$address) || $address["address"]=="") {
                    list($address,$err) = Geocode::checkLatLngByAddress($db->getConnect(), $street_address, $country);
                }
                if (!is_array($address) || !isset($address["address"])) {
                    syslog(LOG_WARNING,'Geocoder failed for "'.$street_address.'"');
                    throw new RuntimeException($err?"Geocoder failed: $err":'Cannot get address for your GPS location '.$street_address,500);
                }
                // Adjust GPS coordinates if any
                if (array_key_exists("latitude", $address) && $address["latitude"]!=null &&
                    array_key_exists("longitude",$address) && $address["longitude"]!=null &&
                    $address["latitude"]!=0 && $address["longitude"]!=0) {
                    $location["lat"] = $address["latitude"];
                    $location["lng"] = $address["longitude"];
                    $address["lat"] = $address["latitude"];
                    $address["lng"] = $address["longitude"];
                } else if (array_key_exists("lat",$address) && $address["lat"]!=null &&
                    array_key_exists("lng",$address) && $address["lng"]!=null &&
                    $address["lat"]!=0 && $address["lng"]!=0) {
                    $location["lat"] = $address["lat"];
                    $location["lng"] = $address["lng"];
                    $address["latitude"] = $address["lat"];
                    $address["longitude"] = $address["lng"];
                }
                list($location,$address) = DestinationsApi::adjustAddressLocationGPS($location,$address);
                if (is_array($address) && array_key_exists("country",$address)) {
                    $gps_country_code = $address["country"]; // Geocoded
                }
            }
            
            // Step 0. Check if we are in the service area
            /* GeocodeApi::checkWithinTheServiceArea($country,[
                [
                    "type"=>1,
                    "geocode" => [
                        "lat" => $location["lat"],
                        "lng" => $location["lng"]
                    ]
                ]
            ]); //*/
            syslog(LOG_WARNING, "location => " . json_encode($location));

            // Step 1. Get activities
            list($res,$err) = Destinations::byActivity(
                $db->getConnect(), $db->getConnectGPS(), $member_id,
                $location["lat"], $location["lng"], Destinations::ACTIVITY_RADIUS,
                $time, Destinations::TIME_DELTA, $country);
            if (!$res || count($res)<1) {
                if ($err!="") {
                    throw new RuntimeException($err, 500);
                }
                throw new RuntimeException($message, 404);
            }
            syslog(LOG_WARNING,'Recent activity has '.count($res).' trips!');
            //DestinationsApi::debugTrips($res,'0');
            return $this->response(
                array(
                    "trips" => $res,
                    "address" => $address,
                    "country" => $country,
                    "gps_country_code" => $gps_country_code,
                    "street_address" => html_entity_decode($street_address)
                ), 200);
        } catch (RuntimeException $e) {
            $message = $e->getMessage();
            $code = $e->getCode();
            syslog(LOG_WARNING,$message);
        }
        return $this->response(
            array(
                "error" => $message
            ), $code);
    }

    private static function adjustAddressLocationGPS($location,$address) {
        syslog(LOG_WARNING,'DestinationsApi::adjustAddressLocationGPS($location,$address)');
        if (array_key_exists("latitude", $address) && $address["latitude"]!=null &&
            array_key_exists("longitude",$address) && $address["longitude"]!=null &&
            $address["latitude"]!=0 && $address["longitude"]!=0) {
            $location["lat"] = $address["latitude"];
            $location["lng"] = $address["longitude"];
            $address["lat"] = $address["latitude"];
            $address["lng"] = $address["longitude"];
        } else if (array_key_exists("lat",$address) && $address["lat"]!=null &&
            array_key_exists("lng",$address) && $address["lng"]!=null &&
            $address["lat"]!=0 && $address["lng"]!=0) {
            $location["lat"] = $address["lat"];
            $location["lng"] = $address["lng"];
            $address["latitude"] = $address["lat"];
            $address["longitude"] = $address["lng"];
        }
        //syslog(LOG_WARNING,json_encode($address));
        //syslog(LOG_WARNING,"location => " . json_encode($location));
        return [$location,$address];
    }

    public static function debugTrips($trips,$what='0') {
        return; /*
        foreach ($trips as $trip) {
            $leg_fare = $trip['multimodal']['options']['leg_fare'];
            syslog(LOG_WARNING,'>>>>>>> '.$what.' >>>>>>> '.json_encode($leg_fare));
        }*/
    }

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

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

}
