using Microsoft.AspNetCore.Http;
using POCDistance.DAL;
using POCDistance.Models;
using POCDistance.Util;
using System.Collections.Generic;
using System.Linq;

namespace POCDistance.Service
{
    public class LocationService : ILocationService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IDataSourceAdapter _dataAdapter;

        public LocationService(IHttpContextAccessor httpContextAccessor, IDataSourceAdapter dataAdapter)
        {
            _httpContextAccessor = httpContextAccessor;
            _dataAdapter = dataAdapter;
        }
        public List<LocationModel> GetAll()
        {
            var locations = new List<LocationModel>();

            if (!string.IsNullOrEmpty(_httpContextAccessor.HttpContext.Session.GetString("LocationData")))
            {
                locations = _httpContextAccessor.HttpContext.Session.GetObjectFromJson<List<LocationModel>>("LocationData");
            }
            else
            {
                locations = _dataAdapter.GetLocations();
                _httpContextAccessor.HttpContext.Session.SetObjectAsJson("LocationData", locations);
            }
            return locations;
        }

        public List<LocationModel> GetManyByZipCode(string zipCode)
        {

            if (!string.IsNullOrWhiteSpace(zipCode) && zipCode.Length > 1)
            {
                var locations = GetAll();
                var query = locations.Where(l => l.ZipCode.StartsWith(zipCode));
                return query.ToList();
            }
            return new List<LocationModel>();
        }

        public LocationModel GetByZipCode(string zipCode)
        {
            var _location = GetManyByZipCode(zipCode);
            return _location.OrderByDescending(l => l.Country).FirstOrDefault();
        }

        public DistanceModel GetDistanceByZipCode(string zipCode1, string zipCode2)
        {
            double distance = 0.0;
            double loc_lat1, loc_long1, loc_lat2, loc_long2;
            var model = new DistanceModel();

            var location1 = GetByZipCode(zipCode1);
            var location2 = GetByZipCode(zipCode2);

            if (location1 != null
                && location2 != null
                && double.TryParse(location1.Latitude, out loc_lat1)
                && double.TryParse(location1.Longitude, out loc_long1)
                && double.TryParse(location2.Latitude, out loc_lat2)
                && double.TryParse(location2.Longitude, out loc_long2))
            {
                distance = CalculateDistance.GetDistance(loc_lat1, loc_long1, loc_lat2, loc_long2);
                model.Distance = distance.ToString("0.00");
                model.FromCity = location1.City;
                model.ToCity = location2.City;
                model.Unit = "km";
            }

            return model;
        }
    }
}
