<?php

namespace App\Services\GoogleMaps;

use App\Packages\User\Models\User;
use App\Services\GoogleMaps\Request\GoogleGeoCoderQuery;
use App\Services\GoogleMaps\Unit\GoogleAddressUnit;
use App\Services\GoogleMaps\Unit\GoogleLatLngPlaceUnit;
use App\Services\GoogleMaps\Unit\GooglePlaceUnit;
use Illuminate\Support\Collection;

/**
 * Class GoogleGeoService
 * @package App\Services\GoogleMaps
 */
class GoogleGeoService
{
	/**
	 * @var GoogleGeoCoderQuery
	 */
	private $geoCoderQuery;

	public function __construct(GoogleGeoCoderQuery $geoCoderQuery)
	{
		$this->geoCoderQuery = $geoCoderQuery;
	}

	/**
	 * @param $address
	 *
	 * @return GoogleAddressUnit
	 */
	public function getDecodedAddressUnit($address)
	{
		$response = $this->geoCoderQuery->requestExactAddress($address);

		$addressData = null;
		if ($response['status'] === GoogleGeoCoderQuery::STATUS_OK) {
			$addressData = array_get($response, 'results.0');
		}

		return new GoogleAddressUnit($addressData);
	}

    /**
     * @param User $user
     * @param $address
     * @param string|null $lat
     * @param string|null $lng
     *
     * @return GooglePlaceUnit[]|Collection
     */
	public function getPlacesUnits(User $user, $address, $lat = null, $lng = null)
	{
		$locale = 'en';
		$sessionId = $user->uuid;

		$response = $this->geoCoderQuery->requestPlaceList($address, $sessionId, $locale, $lat, $lng);

		$addressData = [];
		if ($response['status'] === GoogleGeoCoderQuery::STATUS_OK) {
			$addressData = array_get($response, 'predictions');
		}

		return collect($addressData)->map(function ($prediction) {
			return new GooglePlaceUnit($prediction);
		});
	}

    /**
     * @param User $user
     * @param $lat
     * @param $lng
     *
     * @return GooglePlaceUnit[]|Collection
     */
	public function getPlacesByLatLng(User $user, $lat, $lng)
	{
		$locale = 'en';
        $sessionId = $user->uuid;

		$response = $this->geoCoderQuery->requestPlaceListLatLng($lat, $lng, $sessionId, $locale);

		$addressData = [];
		if ($response['status'] === GoogleGeoCoderQuery::STATUS_OK) {
			$addressData = array_get($response, 'results');
		}

		return collect($addressData)->map(function ($prediction) {
			return new GoogleLatLngPlaceUnit($prediction);
		});
	}

    /**
     * @param User $user
     * @param string $googleMapsPlaceId
     *
     * @return GoogleAddressUnit
     */
    public function getPlaceDetails(User $user, $googleMapsPlaceId)
    {
        $locale = 'en';
        $sessionId = $user->uuid;

        $response = $this->geoCoderQuery->requestPlaceDetails($googleMapsPlaceId, $sessionId, $locale);

        $addressData = null;
        if ($response['status'] === GoogleGeoCoderQuery::STATUS_OK) {
            $addressData = array_get($response, 'result');
        }

        return new GoogleAddressUnit($addressData);
    }
}
