using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.ServiceModel;
using System.Collections.Generic;
using System.Web.SessionState;
using System.Net;
using System.Text;
using System.Diagnostics;

namespace FactoriesWeb
{
    [ServiceContract(Namespace = "http://tempuri.org/")]
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class FactoriesService : WebService
    {
        [WebMethod(EnableSession = true)]
        [OperationContract]
        public void MergeDataBase(DataBase clientDataBase)
        {
            var dataBase = DataBase.GetInstance(Context);
            dataBase.Factories.AddRange(clientDataBase.Factories);
            dataBase.Offices.AddRange(clientDataBase.Offices);
            dataBase.Stores.AddRange(clientDataBase.Stores);
        }

        [WebMethod(EnableSession = true)]
        [OperationContract]
        public DataBase GetFactoriesAndOffices()
        {
            var dataBase = DataBase.GetInstance(Context);
            return new DataBase { 
                Factories = dataBase.Factories, 
                Offices = dataBase.Offices,
                Products = dataBase.Products
            };
        }

        [WebMethod(EnableSession = true)]
        [OperationContract]
        public List<Store> GetStores(double lowerLeftLat, double lowerLeftLong, double upperRightLat, double upperRightLong)
        {
            var stores = new List<Store>();
            var dataBase = DataBase.GetInstance(Context);

            foreach (var store in dataBase.Stores)
            {
                if (store.Latitude > lowerLeftLat
                  && store.Longitude > lowerLeftLong
                  && store.Latitude <= upperRightLat
                  && store.Longitude <= upperRightLong)
                {
                    stores.Add(store);
                }
            }

            return stores;
        }

        [WebMethod(EnableSession = true)]
        [OperationContract]
        public string GetLocationName(double latitude, double longitude)
        {
            try
            {
                var client = new WebClient();
                var data = client.DownloadData(string.Format("http://ws.geonames.org/findNearbyPlaceName?lat={0}&lng={1}", latitude, longitude));

                XDocument xmlEntries = XDocument.Parse(Encoding.UTF8.GetString(data));

                var geonames = xmlEntries.Descendants("geoname");
                return geonames.Count() > 0 ? (string)geonames.First().Element("name") : "";
            }
            catch (WebException)
            {
                return "";
            }
        }
    }
}
