using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InABox.Avalonia
{
    public class GPSLocation
    {
        // public delegate void LocationEvent(GPSLocation sender);
        // public event LocationEvent? OnLocationFound;

        // public delegate void LocationError(GPSLocation sender, Exception error);
        // public event LocationError? OnLocationError;

        public TimeSpan ScanDelay { get; set; }

        public double Latitude { get; private set; }
        public double Longitude { get; private set; }
        public String Address { get; private set; }

        // private bool bLocating = false;
        public DateTime TimeStamp { get; private set; }

        public GPSLocation() : base()
        {
            TimeStamp = DateTime.MinValue;
            ScanDelay = new TimeSpan(0, 0, 0);
            Address = "Searching for GPS";
        }

        public bool RecentlyLocated
        {
            get
            {
                return (DateTime.Now.Subtract(TimeStamp).Ticks < ScanDelay.Ticks);
            }
        }

        private double DistanceBetween(double sLatitude, double sLongitude, double eLatitude,
                               double eLongitude)
        {
            var radiansOverDegrees = (Math.PI / 180.0);

            var sLatitudeRadians = sLatitude * radiansOverDegrees;
            var sLongitudeRadians = sLongitude * radiansOverDegrees;
            var eLatitudeRadians = eLatitude * radiansOverDegrees;
            var eLongitudeRadians = eLongitude * radiansOverDegrees;

            var dLongitude = eLongitudeRadians - sLongitudeRadians;
            var dLatitude = eLatitudeRadians - sLatitudeRadians;

            var result1 = Math.Pow(Math.Sin(dLatitude / 2.0), 2.0) +
                          Math.Cos(sLatitudeRadians) * Math.Cos(eLatitudeRadians) *
                          Math.Pow(Math.Sin(dLongitude / 2.0), 2.0);

            // Using 3956 as the number of miles around the earth
            var result2 = 3956.0 * 2.0 *
                          Math.Atan2(Math.Sqrt(result1), Math.Sqrt(1.0 - result1));

            return result2;
        }

        // public void GetLocation(bool skiprecentlylocated = false)
        // {
        //     if (bLocating || RecentlyLocated)
        //     {
        //         if (!skiprecentlylocated)
        //             return;
        //     }

        //     bLocating = true;

        //     // Don't reset this on every refresh, otherwise the final UI will randomly get "Searching for GPS" as the address
        //     //Address = "Searching for GPS";

        //     bool bOK = MobileUtils.IsPermitted<Permissions.LocationWhenInUse>().Result;
        //     
        //     Task.Run(async () =>
        //     {

        //         try
        //         {
        //             
        //             if (!bOK)
        //             {
        //                 Latitude = 0.0F;
        //                 Longitude = 0.0F;
        //                 TimeStamp = DateTime.MinValue;
        //                 Address = "GPS Services Disabled";
        //                 Device.BeginInvokeOnMainThread(() =>
        //                 {
        //                     OnLocationError?.Invoke(this, new Exception("Please enable GPS Services to continue"));
        //                 });
        //                 bOK = false;
        //                 bLocating = false;
        //             }
        //             else
        //             {

        //                 try
        //                 {
        //                     var request = new GeolocationRequest(GeolocationAccuracy.Best, new TimeSpan(0, 0, 20));
        //                     var location = await Geolocation.GetLocationAsync(request);

        //                     if (location != null)
        //                     {

        //                         //if (location.IsFromMockProvider)
        //                         //{
        //                         //    Device.BeginInvokeOnMainThread(() =>
        //                         //    {
        //                         //        OnLocationError?.Invoke(this, new Exception("Mock GPS Location Detected!\nPlease correct and restart TimeBench."));
        //                         //    });
        //                         //}
        //                         //else
        //                         {

        //                             Latitude = location.Latitude;
        //                             Longitude = location.Longitude;
        //                             TimeStamp = DateTime.Now;


        //                             String sErr = "";
        //                             Placemark address = null;
        //                             try
        //                             {
        //                                 var addresses = await Geocoding.GetPlacemarksAsync(Latitude, Longitude);
        //                                 double maxdist = double.MaxValue;
        //                                 foreach (var cur in addresses.Where(x => !String.IsNullOrEmpty(x.Thoroughfare)))
        //                                 {
        //                                     var delta = Location.CalculateDistance(location, cur.Location, DistanceUnits.Kilometers);
        //                                     if (delta < maxdist)
        //                                     {
        //                                         address = cur;
        //                                         maxdist = delta;
        //                                     }
        //                                 }

        //                             }
        //                     
        //                             catch (Exception ee2)
        //                             {
        //                                 sErr = ee2.Message;
        //                                 //address = null;
        //                             }
        //                             if (address != null)
        //                                 Address = String.Format("{0} {1} {2}", address.SubThoroughfare, address.Thoroughfare, address.Locality);
        //                             else
        //                                 Address = String.Format("Lat: {0}, Lng: {1}", Latitude, Longitude);

        //                             if (location.IsFromMockProvider)
        //                                 Address = "** " + Address;

        //                             if (!String.IsNullOrEmpty(sErr))
        //                                 Address = String.Format("{0} (ERROR: {1})", Address, sErr);

        //                             Device.BeginInvokeOnMainThread(() =>
        //                             {
        //                                 OnLocationFound?.Invoke(this);
        //                             });
        //                             bLocating = false;
        //                         }

        //                     }
        //                     else
        //                     {
        //                         Latitude = 0.00;
        //                         Longitude = 0.00;
        //                         TimeStamp = DateTime.MinValue;
        //                         bLocating = false;
        //                         Device.BeginInvokeOnMainThread(() =>
        //                         {
        //                             OnLocationError?.Invoke(this, new Exception("Unable to get GPS Location"));
        //                         });

        //                     }

        //                 }
        //                 catch (Exception e)
        //                 {
        //                     bLocating = false;
        //                     Device.BeginInvokeOnMainThread(() =>
        //                     {
        //                         OnLocationError?.Invoke(this, e);
        //                     });
        //                 }
        //             }
        //         }
        //         catch (Exception e)
        //         {
        //             
        //         }

        //         bLocating = false;
        //     });


        // }

    }
}
