using Business.ViewModels;
using Business.Services.Abstract;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using MongoDB.Driver;
using Common.Models;
using Microsoft.Extensions.Options;
using Common.Utility;
using Common.Configuration;

namespace Business.Services.Concrete
{
    public class DistanceService : IDistanceService
    {
        private readonly IMongoCollection<DistanceResult> _distance;
        private readonly DatabaseConfiguration _settings;

        public DistanceService(IOptions<DatabaseConfiguration> settings)
        {
            _settings = settings.Value;
            var client = new MongoClient(_settings.ConnectionString);
            var database = client.GetDatabase(_settings.DatabaseName);
            _distance = database.GetCollection<DistanceResult>("PocZip");

        }
        public async Task<ErrorModel<DistanceModel>> CalculateDistance(string source, string destination)
        {
            var vResult = new ErrorModel<DistanceModel>(null);
            Distance distance = new Distance();

            double distanceinmiles = 0.00;
            List<DistanceResult> items;
            DistanceResult drt = new DistanceResult();
            DistanceResult drt1 = new DistanceResult();
            try
            {
                items = await _distance.Find(c => true).ToListAsync();
                items.ToList().ForEach(item =>
                {
                    if ((source == item.ZipCode) && !string.IsNullOrEmpty(item.City))
                    {
                        drt.Latitude = item.Latitude;
                        drt.Longitude = item.Longitude;
                        drt.ZipCode = item.ZipCode;
                        drt.City = item.City;
                    }
                    if ((destination == item.ZipCode) && !string.IsNullOrEmpty(item.City))
                    {
                        drt1.Latitude = item.Latitude;
                        drt1.Longitude = item.Longitude;
                        drt1.ZipCode = item.ZipCode;
                        drt1.City = item.City;
                    }
                });
                distanceinmiles = distance.CalculateDistance(drt.Latitude, drt1.Latitude, drt.Longitude, drt1.Longitude);
                DistanceModel model = new DistanceModel();
                model.Distance = distanceinmiles;
                model.Unit = "km";
                model.SourceAssociateCity = drt.City;
                model.DestinationAssociateCity = drt1.City;
                vResult.Data = model;
            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }
            return vResult;
        }

        public async Task<ErrorModel<List<ZipModel>>> GetPostalCode(string zipCode)
        {
            var vResult = new ErrorModel<List<ZipModel>>(null);
            List<DistanceResult> items;
            List<ZipModel> models = new List<ZipModel>();
            DistanceResult drt = new DistanceResult();
            try
            {

                items = await _distance.Find(c => true).ToListAsync();
                items.ToList().ForEach(item =>
                {
                    ZipModel zipmodel = new ZipModel();

                    if ((item.ZipCode.ToString().StartsWith(zipCode.ToString())) && (!string.IsNullOrEmpty(item.City)))
                    {
                        zipmodel.ZipCode = item.ZipCode;
                        models.Add(zipmodel);
                    }
                    vResult.Data = models;
                });
            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }
            return vResult;
        }
    }
}
