using GMCabsDriverAssistant.Messages;
using GMCabsDriverAssistant.Models;
using GMCabsDriverAssistant.Utils;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Maui;
using Microsoft.Maui.Controls;

namespace GMCabsDriverAssistant.Services
{

    public class LocationService
    {
        private const double LOCATION_DISTANCE = 0.015; // 15 meters
        readonly bool stopping = false;
        private double lastLatitude = 0;
        private double lastLongitude = 0;

        public LocationService()
        {
        }

        public async Task Run(CancellationToken token)
        {
            await Task.Run(async () =>
            {
                while (!stopping)
                {
                    token.ThrowIfCancellationRequested();
                    try
                    {
                        await Task.Delay(10000);

                        var request = new GeolocationRequest(GeolocationAccuracy.Best);
                        var location = await Geolocation.GetLocationAsync(request);
                        if (location != null)
                        {
                            var message = new LocationMessage
                            {
                                Latitude = location.Latitude,
                                Longitude = location.Longitude
                            };
                            await UpdateLocationOnServer(location.Latitude, location.Longitude);

                            Device.BeginInvokeOnMainThread(() =>
                            {
                                MessagingCenter.Send<LocationMessage>(message, "Location");
                            });
                        }
                    }
                    catch (Exception ex)
                    {
                        Device.BeginInvokeOnMainThread(() =>
                        {
                            var errormessage = new LocationErrorMessage();
                            MessagingCenter.Send<LocationErrorMessage>(errormessage, "LocationError");
                        });
                    }
                }
                return;
            }, token);
        }
        private async Task UpdateLocationOnServer(double currentLatitude, double currentLongitude)
        {
            var token = Preferences.Get(SecureStorageData.Token,"");
            if (token != null)
            {
                GMCabsDriverService gmCabsDriverService = new GMCabsDriverService();
                LocationUpdateRequestDto locationUpdateRequestDto = new LocationUpdateRequestDto();
                if (lastLatitude == 0.00 && lastLongitude == 0.00)
                {
                    lastLatitude = currentLatitude;
                    lastLongitude = currentLongitude;
                    locationUpdateRequestDto.Latitude = currentLatitude;
                    locationUpdateRequestDto.Longitude = currentLongitude;
                    locationUpdateRequestDto.Imei = Preferences.Get("imeiNumber", null);
                    if (!string.IsNullOrEmpty(locationUpdateRequestDto.Imei))
                    {
                        await gmCabsDriverService.SendDriverLocationTablet(locationUpdateRequestDto);
                    }
                    else
                    {
                        await gmCabsDriverService.SendDriverLocation(token, locationUpdateRequestDto);
                    }


                    Preferences.Set("lastLat", currentLatitude);
                    Preferences.Set("lastLng", currentLongitude);
                }
                else
                {
                    Location lastLocation = new Location(lastLatitude, lastLongitude);
                    Location currentLocation = new Location(currentLatitude, currentLongitude);
                    double kilometers = Location.CalculateDistance(lastLocation, currentLocation, DistanceUnits.Kilometers);
                    if (kilometers > LOCATION_DISTANCE)
                    {

                        lastLatitude = currentLatitude;
                        lastLongitude = currentLongitude;
                        locationUpdateRequestDto.Latitude = currentLatitude;
                        locationUpdateRequestDto.Longitude = currentLongitude;
                        locationUpdateRequestDto.Imei = Preferences.Get("imeiNumber", null);
                        if (!string.IsNullOrEmpty(locationUpdateRequestDto.Imei))
                        {
                            await gmCabsDriverService.SendDriverLocationTablet(locationUpdateRequestDto);
                        }
                        else
                        {
                            await gmCabsDriverService.SendDriverLocation(token, locationUpdateRequestDto);
                        }

                        Preferences.Set("lastLat", currentLatitude);
                        Preferences.Set("lastLng", currentLongitude);
                    }
                }

            }
        }
    }

}
