<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

function parse_citystatezip($citystatezip) {
    $citystatezip = strtoupper(trim($citystatezip));

    $fullregex = "/^(.+), ?(.+)[,| |, ]([0-9]{5})(-[0-9]{4})?$/";
    $citystateregex = "/^(\w+)[,\s]+([A-Z]{2,})+$/";

    if (!preg_match($fullregex, $citystatezip, $matches)) {
        if (!preg_match($citystateregex, $citystatezip, $matches)) {
            return null;
        }
    }

    return [
        "city" => $matches[1],
        "state" => $matches[2],
        "zip" => isset($matches[3]) ? $matches[3] : null
    ];
}

function parse_citystate($citystate) {
    $citystate = strtoupper(trim($citystate));

    $regex = "/^(\w+)[,\s]+([A-Z]{2,})+$/";

    if (!preg_match($regex, $citystate, $matches)) {
        return null;
    }

    return [
        "city" => $matches[1],
        "state" => $matches[2]
    ];
}

function geocode_returnresult($query) {
    global $SETTINGS, $database;
    
    $geocoder = new \Geocoder\ProviderAggregator();
    $adapter = new \Http\Adapter\Guzzle6\Client();

    $chain = new \Geocoder\Provider\Chain\Chain([
        new \Geocoder\Provider\LocalDatabase\LocalDatabase($database),
        new \Geocoder\Provider\Mapbox\Mapbox($adapter, $SETTINGS["mapbox_key"]),
        new \Geocoder\Provider\MapQuest\MapQuest($adapter, $SETTINGS["mapquest_key"])
    ]);

    $geocoder->registerProvider($chain);

    $results = $geocoder->geocodeQuery($query);


    if ($results->count() > 0) {
        $result = $results->first();
    } else {
        header("Content-Type: application/json");
        return [
            "status" => "ERROR",
            "message" => "That address doesn't seem to exist. If this is an error, please send the full address (including city, state, and ZIP) to support@netsyms.com.",
            "address" => [
                "street" => "",
                "postalCode" => ""
            ],
            "coords" => [
                0,
                0
            ],
            "accuracy" => [
                "ok" => false
            ],
            "provider" => ""
        ];
    }

    $geolatitude = $result->getCoordinates()->getLatitude();
    $geolongitude = $result->getCoordinates()->getLongitude();

    $accurate = !empty($result->getStreetNumber());

    if ($accurate) {
        $address = implode(" ", [$result->getStreetNumber(), $result->getStreetName()]);
    } else {
        $address = $result->getStreetName();
    }


    return [
        "status" => "OK",
        "address" => [
            "street" => ucwords(strtolower(StreetNormalizer::normalizeAddress($address))),
            "postalCode" => $result->getPostalCode()
        ],
        "coords" => [
            $geolatitude,
            $geolongitude
        ],
        "accuracy" => [
            "ok" => $accurate
        ],
        "provider" => $result->getProvidedBy()
    ];
}

function geocode_addrstring($address) {
    $query = Geocoder\Query\GeocodeQuery::create($address)->withLimit(1);
    return geocode_returnresult($query);
}

/**
 * Geocode an address.
 * @global type $SETTINGS
 * @param type $number
 * @param type $street
 * @param type $unit
 * @param type $city
 * @param type $state
 * @param type $zip
 * @param type $country
 * @param type $type
 * @return type
 */
function geocode($number, $street, $unit = null, $city, $state, $zip = null, $country = null, $type = null) {
    $address = "$number $street $city $state";
    $origaddress = "$number $street";

    $query = Geocoder\Query\GeocodeQuery::create($address)
            ->withLimit(1)
            ->withData("number", $number)
            ->withData("street", $street)
            ->withData("city", $city)
            ->withData("state", $state);
    if (!is_null($zip) && preg_match("/^([0-9]{5})/", $zip, $matches)) {
        if (count($matches) > 0) {
            $query = $query->withData("zip", $matches[0]);
        }
    }
    if (!is_null($unit) && !empty($unit)) {
        $query = $query->withData("unit", $unit);
    }

    if (!is_null($type) && count(array_diff(explode("|", $type), $SETTINGS["address_types"])) == 0) {
        $query = $query->withData("locationtype", $type);
    }

    if (!is_null($country) && preg_match("/^[A-Z]{2}$/", $country)) {
        $query = $query->withData("country", $country);
    }

    return geocode_returnresult($query);
}
