using ErsPos.Service.ProductRepository;
using ErsPos.Service.RestaurantRepository;
using ErsPos.Service.UserRepository;
using ErsPos.Service.ViewModels;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Results;
using BeachOrder.Helpers;

namespace BeachOrder.Controllers
{
    public class WebApiController : ApiController
    {
        [Route("api/GetAll")]
        [HttpGet]
        public JObject GetAll(string DepNo = "")
        {
            using (ProductRepository repo = new ProductRepository())
            {
                //repo.GetList(DepNo);
                return repo.GetJson(DepNo);
            }
        }

        [Route("api/EmptyTables")]
        [HttpGet]
        public void EmptyTables()
        {
            using (RestaurantRepository repo = new RestaurantRepository())
            {
                repo.EmptyTables();
            }
        }

        [Route("api/DeskList")]
        [HttpGet]
        public JObject DeskList(string departmentId)
        {
            if (String.IsNullOrEmpty(departmentId))
            {
                return JObject.FromObject(new Result { Error = "DepartmanId null olamaz!" });
            }
            else
            {
                using (RestaurantRepository repo = new RestaurantRepository())
                {
                    try
                    {
                        var desks = repo.GetDeskList(departmentId).ToList();
                        //var paymentTypes = repo.GetPaymentTypes();
                        return JObject.FromObject(new { desks });
                    }
                    catch (Exception ex)
                    {
                        return JObject.FromObject(new Result { Error = ex.Message });
                    }
                }
            }
        }

        [Route("api/GetPaymentTypes")]
        public JObject GetPaymentTypes()
        {
            using (RestaurantRepository repo = new RestaurantRepository())
            {
                try
                {
                    var paymentTypes = repo.GetPaymentTypes();
                    return JObject.FromObject(new { paymentTypes });
                }
                catch (Exception ex)
                {
                    return JObject.FromObject(new { paymentTypes = "[]" });
                }
            }
        }

        // Masaya açan garson devam ettirsin parametresi POSV5'de açıksa
        // Sipariş gönderilirken sipariş veren garsonla masayı açan garsonun aynı kullanıcı olup olmadığı kontrol edilir
        // eğer aynı garson ise işleme devam eder ve sipariş verir. Eğer farklı garsonsa uyarı verir.
        [Route("api/AuthorityCheck")]
        [HttpGet]
        public JObject AuthorityCheck(string garsonId="",string masaNo="")
        {
            if (garsonId.ToSafeString() != "" && masaNo.ToSafeString() != "")
            {
                using (RestaurantRepository repo = new RestaurantRepository())
                {
                    try
                    {
                        return JObject.FromObject(new Result { Message = repo.AuthorityCheck(garsonId, masaNo) });
                    }
                    catch (Exception ex)
                    {
                        return JObject.FromObject(new Result { Error = ex.ToExceptionString() });
                    }
                }
            }
            else
            {
                return JObject.FromObject(new Result { Error = "invalid parameters!" });
            }
            
        }
        

        [Route("api/CallGarson")]
        [HttpGet]
        public string CallGarson(string masaNo = "", string message = "")
        {
            string result;
            if (masaNo.ToSafeString() != "" && message.ToSafeString() != "")
            {
                using (RestaurantRepository repo = new RestaurantRepository())
                {                    
                    try
                    {
                        result= repo.CallGarson(masaNo, message);
                        return result;
                    }
                    catch (Exception ex)
                    {
                        result = ex.ToExceptionString();
                        return result;
                    }
                }
            }
            else
            {
                result = "Garson Çağırırken Hata Oluştu!";
                return result;
            }

        }

        [Route("api/Login")]
        [HttpGet]
        public JObject Login(string departmanCode, string password)
        {
            if (String.IsNullOrEmpty(departmanCode) || String.IsNullOrEmpty(password))
            {
                return JObject.FromObject(new Result { Error = "Kulanıcı bilgileri boş olamaz!" });
            }
            else
            {
                using (UserRepository repo = new UserRepository())
                {
                    try
                    {
                        var _user = repo.Login(departmanCode, password);
                        //Helpers.Helpers.SetLogin(_user);
                        if (_user == null)
                        {
                            return JObject.FromObject(new Result { Error = "Kullanıcı Bulunamadı" });
                        }
                        else
                        {
                            var signalR = new BeachOrder.Hub.Notification();
                            int activeUserCount = signalR.activeUserCount();
                            if (_user.UserCount > activeUserCount)
                            {
                                var roles = repo.GetRoles(int.Parse(_user.RoleId));
                                return JObject.FromObject(new { user = _user, roles = roles });
                            }
                            else
                            {
                                return JObject.FromObject(new Result { Error = "Maksimum kullanıcı sayısı aşıldı!" });
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        return JObject.FromObject(new Result { Error = ex.Message });
                    }
                }
            }
        }

        [Route("api/AddOrder")]
        [HttpPost]
        public JObject AddOrder([FromBody]string data)
        {
          
            if (String.IsNullOrEmpty(data))
            {
                return JObject.FromObject(new Result { Error = "Herhangi bir sipariş isteği bulunamadı!" });
            }

            else
            {
                var request = JsonConvert.DeserializeObject<System.Collections.Generic.List<RequestViewModel>>(data);
                //JsonConvert.DeserializeObject<List<RequestViewModel>>(data);
                // login olan adamın bilgilerini her defasında javascript seviyesinden göndermeyelim artık bu şeklide okuyalım.
                //var user = Helpers.Helpers.GetLogin();
                using (ProductRepository repo = new ProductRepository())
                {
                    try
                    {
                        string message = "";
                        foreach (var item in request)
                        {
                            repo.Add(item);
                            message += item.DeskNo + ",";
                        }

                        return JObject.FromObject(new Result { Message = message + " numaralı masa için sipariş gönderildi." });
                    }
                    catch (Exception ex)
                    {
                        return JObject.FromObject(new Result { Error = ex.Message });
                    }

                }
            }
        }

        Boolean CheckNet()
        {
            try
            {
                using (var client = new WebClient())
                {
                    using (client.OpenRead("http://clients3.google.com/generate_204"))
                    {
                        return true;
                    }
                }
            }
            catch
            {
                return false;
            }
        }

        [Route("api/AddDetail")]
        [HttpGet]
        public JObject AddDetail(string data)
        {
            if (string.IsNullOrEmpty(data))
            {
                return JObject.FromObject(new Result { Error = "model boş olamaz" });
            }
            else
            {
                try
                {
                    var model = JsonConvert.DeserializeObject<ProductDetailViewModel>(data);
                    using (ProductRepository repo = new ProductRepository())
                    {
                        var result = repo.AddDetail(model);
                        if (result.Error != null)
                        {
                            JObject.FromObject(new Result { Error = "NOK" });
                        }
                        else
                        {
                            return JObject.FromObject(new Result { Message = "OK" });
                        }
                    }
                    return JObject.FromObject(new Result { Message = "OK" });
                }
                catch (Exception ex)
                {
                    return JObject.FromObject(new Result { Error = "NOK" });
                }
            }
        }

        [Route("api/ViewOrClose")]
        [HttpGet]
        public JObject ViewOrClose(string data /*string isViewOrClose,string departmentId="", string deskNo ="",string paymentType=""*/)
        {
            if (!String.IsNullOrEmpty(data))
            {
                var model = JsonConvert.DeserializeObject<SeeOrCloseModel>(data);
                if (String.IsNullOrEmpty(model.DepartmentId) || String.IsNullOrEmpty(model.DeskNo))
                {
                    return JObject.FromObject(new Result { Error = "DeparmanId ve Masa numarası boş olamaz!" });
                }
                else
                {
                    using (ProductRepository repo = new ProductRepository())
                    {
                        try
                        {
                            if (model.IsViewOrClose == "view")
                            {
                                var view = repo.View(model.DepartmentId, model.DeskNo);
                                return JObject.FromObject(new { view });
                            }
                            else if (model.IsViewOrClose == "close")
                            {
                                var message = repo.Close(model);
                                return JObject.FromObject(new Result { Message = message });
                            }
                            else
                            {
                                return JObject.FromObject(new Result { Message = "Tanımsız istek!" });
                            }
                        }
                        catch (Exception ex)
                        {
                            return JObject.FromObject(new Result { Error = ex.Message });
                        }
                    }
                }
            }
            else
            {
                return JObject.FromObject(new Result { Message = "Json data boş olamaz" });
            }
        }

        [Route("api/AddOrderWithQrCode")]
        [HttpGet]
        public JObject AddOrderWithQrCode(string data = "")
        {
            if (string.IsNullOrEmpty(data))
            {
                return JObject.FromObject(new Result { Error = "Error" });
            }
            else
            {
                var model = JsonConvert.DeserializeObject<RequestViewModel>(data);
                if (model != null)
                {
                    // ekle
                    return JObject.FromObject(new Result { Message = "OK" });

                    // kapat
                }
                else
                {
                    return JObject.FromObject(new Result { Error = "Error" });
                }
            }
        }

        [Route("api/ModifyNotification")]
        [HttpGet]
        public JObject ModifyNotification(string counter="")
        {
            if (string.IsNullOrEmpty(counter))
                return JObject.FromObject(new Result { Error = "NOK" });

            using (ProductRepository repo = new ProductRepository())
            {
                try
                {
                    int c = int.Parse(counter);
                    repo.UpdateNotification(c);
                    return JObject.FromObject(new Result { Message = "OK" });
                }
                catch (Exception ex)
                {
                    return JObject.FromObject(new Result { Error = "NOK" });
                }
            }
        }

        [Route("api/Yazdir")]
        [HttpGet]
        public JObject Yazdir(int? Id = 0)
        {
            if (Id == 0)
                return JObject.FromObject(new Result { Error = "NOK" });

            using (RestaurantRepository repo = new RestaurantRepository())
            {
                try
                {
                    var result = repo.Yazdir(Id);   
                    return JObject.FromObject(new Result { Message = "OK" });
                }
                catch (Exception ex)
                {
                    return JObject.FromObject(new Result { Error = "NOK" });
                }
            }
        }

        [Route("api/Transfer")]
        [HttpGet]
        public JObject Transfer(string From = "", string To = "",string DepNo = "",string YeniMasaDepKodu = "")
        {
            if (To == "" && DepNo == "" && From == "")
                return JObject.FromObject(new Result { Error = "Invalid parameters" });

            using (ProductRepository repo = new ProductRepository())
            {
                try
                {
                    var result = repo.MasaTransfer(DepNo,From,To, YeniMasaDepKodu);
                    return JObject.FromObject(result);
                }
                catch (Exception ex)
                {
                    return JObject.FromObject(new Result { Error = "NOK: " + ex.ToString() });
                }
            }
        }


        [Route("api/UrunTransfer")]
        [HttpGet]
        public JObject UrunTransfer(string From = "", string To = "", int ProductId = 0 ,int Quantity = 0,string DepNo = "")
        {
            if (To == "" && ProductId == 0 && From == "" && Quantity == 0 && DepNo == "")
                return JObject.FromObject(new Result { Error = "Invalid parameters" });

            using (ProductRepository repo = new ProductRepository())
            {
                try
                {
                    var result = repo.UrunTransfer(From, To, ProductId, Quantity);
                    if (result.Error == null)
                    {
                        var resultData = repo.View(DepNo, From);
                        if (resultData.Count() == 1 && resultData[0].Quantity == null)
                        {
                            repo.OnlyClose(DepNo, From);
                        }
                        return JObject.FromObject(result);
                    }
                    else
                    {
                        return JObject.FromObject(new Result { Error = "ürün transferi sırasında hata oluştu." });
                    }
                    
                }
                catch (Exception ex)
                {
                    return JObject.FromObject(new Result { Error = ex.InnerException.Message.ToString()});
                }
            }
        }

        [Route("api/BulkTransfer")]
        [HttpGet]
        public JObject BulkTransfer(string DepNo= "", string From = "", string To = "", string Data = "")
        {
            if (DepNo == "" && To == "" && Data == "" && From == "")
                return JObject.FromObject(new Result { Error = "Invalid parameters" });

            using (ProductRepository repo = new ProductRepository())
            {
                try
                {
                    var model = repo.View(DepNo, From);
                    foreach (var item in model)
                    {
                        int adet = int.Parse(item.Quantity.ToString());
                       var result = repo.UrunTransfer(From, To, item.ID, adet);
                    }
                    var resultData = repo.View(DepNo, From);
                    if (resultData.Count() == 1 && resultData[0].Quantity == null)
                    {
                        repo.OnlyClose(DepNo, From);
                    }
                    return JObject.FromObject(new Result { Message = "OK"});
                }
                catch (Exception ex)
                {
                    return JObject.FromObject(new Result { Error = ex.Message.ToString() });
                }
            }
        }

        /// <summary>
        ///         web api de eğer route belirlez isek webapi/api/GetDepartments şeklinde ulaşabiliriz
        ///         ancak bunun yerine route belirleyip daha kısa bir url den erişebiliriz
        ///         HttpGet Default tur bu attribute standart olarak yazılmalı.
        /// </summary>
        [Route("api/GetDepartments")]
        [HttpGet]
        public JObject GetDepartments()
        {
            using (RestaurantRepository repo= new RestaurantRepository())
            {
                JObject list = new JObject();
                try
                {
                    list = repo.GetDepartmentsWithTables();
                    return JObject.FromObject(new { list });
                }
                catch (Exception ex)
                {
                    return JObject.FromObject(new { list ,Error = ex.InnerException.Message.ToString()});
                }
                
            }
        }

        [Route("api/FindCustomer")]
        [HttpGet]
        public JObject FindCustomer(string Name = "", string Lastname = "" , string CartNo = "", string RoomNo= "")
        {
            //  if (string.IsNullOrEmpty(Name) && string.IsNullOrEmpty(Lastname))
            //    return JObject.FromObject(new Result { Error = "Geçersiz parametreler" });
            
            using (RestaurantRepository repo = new RestaurantRepository())
            {
                if (CartNo =="" && RoomNo=="")
                    return JObject.FromObject(new Result { Error = "Oda No veya Kart No dolu olmalıdır." });
                if (CartNo == "")
                {
                    try
                    {
                        var result = repo.FindCustomerByRoomNo(RoomNo);
                        return JObject.FromObject(result);
                    }
                    catch (Exception ex)
                    {
                        return JObject.FromObject(new Result { Error = "Sorgulama yapılamadı!" });
                    }
                }
                else if (RoomNo == "")
                {
                    try
                    {
                        var result = repo.FindCustomerByCartNo(CartNo);
                        return JObject.FromObject(result);
                    }
                    catch (Exception)
                    {
                        return JObject.FromObject(new Result { Error = "Sorgulama yapılamadı!" });
                    }
                    
                }
                else
                {
                    try
                    {
                        var result = repo.FindCustomerByCartNo(CartNo);
                        return JObject.FromObject(result);
                    }
                    catch (Exception)
                    {
                        return JObject.FromObject(new Result { Error = "Sorgulama yapılamadı!" });
                    }
                }

            }
        }

        [Route("api/GetAppConfig")]
        [HttpGet]
        public JObject GetAppConfig()
        {
            using (RestaurantRepository repo = new RestaurantRepository())
            {
                try
                {
                    Parameters prms = repo.GetAppMode();
                    return JObject.FromObject(prms);
                }
                catch (Exception ex)
                {
                    return JObject.FromObject(new Result { Error = ex.InnerException.ToString() });
                }
               
            }
        }

        [Route("api/lisansyenile")]
        [HttpGet]
        public JObject LisansYenile(int day = 0,bool refresh = false)
        {
            try
            {
                if (!refresh)
                {
                    var a = System.Runtime.Caching.MemoryCache.Default.Remove("lisans");
                    var b = System.Runtime.Caching.MemoryCache.Default.AddOrGetExisting("lisans", Models.Lisans.Lisansli, DateTimeOffset.Now.AddDays(day == 0 ? 15 : day));
                    if (day > 0)
                    {
                        return JObject.FromObject(new Result { Message = "Ok" });
                    }
                    else
                    {
                        return JObject.FromObject(new Result { Message = "Gün parametresi 0 geldi ve 15 günlük ayarlandı" });
                    }
                }
                else
                {
                    var a = System.Runtime.Caching.MemoryCache.Default.Remove("lisans");
                    return JObject.FromObject(new Result { Message = "Cache silindi" });
                }
            }
            catch (Exception ex)
            {
                return JObject.FromObject(new Result { Error = ex.ToExceptionString() });
            }
        }

        [Route("api/AddPayment")]
        [HttpGet]
        public JObject AddPayment(string paymentListModel ="", string depno="", string masaNo="")
        {
            if (paymentListModel.ToSafeString() != "" && depno.ToSafeString() != "" && masaNo.ToSafeString() != "")
            {
                var paymentList = JsonConvert.DeserializeObject<List< PaymentModel>>(paymentListModel);
                using (ProductRepository repo = new ProductRepository())
                {
                    var logs = new List<Result>();
                    foreach (var item in paymentList)
                    {
                        logs.Add(repo.AddPayment(item, masaNo, depno));
                    }
                    return JObject.FromObject(new { logs });
                }
            }
            else
            {
                return JObject.FromObject(new Result { Error = "invalid parameters" });
            }
        }
    }
}
