using GuigleApi;
using GuigleApi.Models.Extension;
using GuigleApi.Models.Response;
using Microsoft.EntityFrameworkCore.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;

namespace GreenTree.Maschinenbestellungen.Services.Geolocator
{
    public class GoogleGeocodingService : IGeocodingService
    {
        #region Contants

        // The default address component types to check for an address validation
        private readonly string[] _defaultCheckComponents = 
        {
            "street_number",
            "route",
            "locality",
            "country",
            "postal_code"
        };

        #endregion

        #region DI fields

        // The global Google API settings
        private readonly GoogleApiOptions _googleApiOptions;

        #endregion

        #region Ctor

        /// <summary>
        /// Initializes a new instance of the GoogleGeocodingService
        /// </summary>
        /// <param name="googleApiOptions">Global Google API options.</param>
        public GoogleGeocodingService(
            GoogleApiOptions googleApiOptions)
        {
            _googleApiOptions = googleApiOptions;
        }

        #endregion

        #region Implementation

        /// <summary>
        /// Checks an address search string for valid street address
        /// </summary>
        /// <param name="searchString">The address search string.</param>
        public bool IsValidAddress(string searchString)
        {
            return IsValidAddress(searchString, _defaultCheckComponents);
        }

        /// <summary>
        /// Checks an address search string for valid street address
        /// </summary>
        /// <param name="searchString">The address search string.</param>
        /// <param name="addressComponents">
        /// The address components the API result shall be checked for 
        /// (NULL if validation check shall succeed).
        /// </param>
        public bool IsValidAddress(string searchString, string[] addressComponents)
        {
            if (!_googleApiOptions.Enabled)
                return true;

            if (addressComponents == null)
                return true;

            var client = new HttpClient();

            var googleGeocodingApi = new GoogleGeocodingApi(_googleApiOptions.ApiKey);
            var addressSearchResult = googleGeocodingApi.SearchAddress(
                client, searchString);

            var result = addressSearchResult.Result;

            if (result.Status != "OK")
                return false;

            if (result.Results.Count == 0)
                return false;

            var addressResult = result.Results[0];

            foreach (var addressComponent in addressComponents)
            {
                if (!addressResult.AddressComponents.Exists(a => a.Types.Any(t => t.ToString() == addressComponent)))
                    return false;
            }

            return true;
        }

        #endregion
    }
}
