using Foresight.Fleet.Services.JobSite;
using Foresight.Standard;
using IronIntel.Contractor.FilterQ;
using IronIntel.Contractor.JobSites;
using IronIntel.Contractor.Machines;
using IronIntel.Contractor.MapView;
using IronIntel.Contractor.Users;
using IronIntel.Services;
using IronIntel.Services.Business.Admin;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace IronIntel.Contractor.Site
{
    public class JobSitesBasePage : ContractorBasePage
    {
        protected void ProcessRequest()
        {
            object result = null;
            try
            {
                string methodName = Request.Params["MethodName"];
                if (methodName != null)
                {
                    switch (methodName)
                    {
                        case "GetJobSites":
                            result = GetJobSites();
                            break;
                        case "SaveJobSite":
                            result = SaveJobSite();
                            break;
                        case "DeleteJobSite":
                            result = DeleteJobSite();
                            break;
                        case "SaveJobSiteMachines":
                            result = SaveJobSiteMachines();
                            break;
                        case "GetMachines":
                            result = GetMachines();
                            break;
                        case "GetSelectedAssets":
                            result = GetSelectedAssets();
                            break;
                        case "AddAssetToJobSite":
                            result = AddAssetToJobSite();
                            break;
                        case "RemoveAssetFromJobSite":
                            result = RemoveAssetFromJobSite();
                            break;
                        case "ChangeAssetOnSiteState":
                            result = ChangeAssetOnSiteState();
                            break;
                        case "GetMachineTypes":
                            result = GetMachineTypes();
                            break;
                        case "GetMachinesByType":
                            result = GetMachinesByType();
                            break;
                        case "GetBindingMachines":
                            result = GetBindingMachines();
                            break;
                        case "ImportJobsitePolygon":
                            result = ImportJobsitePolygon();
                            break;
                        case "GetJobSiteUsers":
                            result = GetJobSiteUsers();
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                SystemParams.WriteLog("error", "JobSitesBasePage", ex.Message, ex.ToString());
                throw ex;
            }
            string json = JsonConvert.SerializeObject(result);
            Response.Write(json);
            Response.End();
        }

        private object GetJobSites()
        {
            try
            {
                JobSiteViewItem[] items = null;
                if (GetCurrentLoginSession() != null)
                {
                    var s = Request.Form["ClientData"];
                    s = HttpUtility.HtmlDecode(s);

                    var jss = CreateClient<JobSiteProvider>().GetJobSiteItems(SystemParams.CompanyID, s);
                    List<JobSiteViewItem> list = new List<JobSiteViewItem>();

                    foreach (var js in jss)
                    {
                        JobSiteViewItem item = new JobSiteViewItem();
                        item.ID = js.ID;
                        item.Name = js.Name;
                        item.BaseOnMachineID = js.BaseonMachineID;
                        item.Code = js.Code;
                        item.Types = new string[] { js.JobSiteTypes };
                        item.ColorString = js.Color;
                        System.Drawing.Color color = System.Drawing.Color.Orange;
                        try
                        {
                            color = System.Drawing.ColorTranslator.FromHtml(item.ColorString);
                        }
                        catch
                        {
                        }
                        item.Color = new IIColor() { Alpha = color.A, Red = color.R, Green = color.G, Blue = color.B };

                        item.Latitude = js.Latitude;
                        item.Longitude = js.Longitude;
                        item.StartDate = js.StartDate == null ? DateTime.MinValue : js.StartDate.Value;
                        item.EndDate = js.EndDate == null ? DateTime.MinValue : js.EndDate.Value;
                        item.Radius = js.Radius;
                        item.Radius_UOM = js.RadiusUOM;
                        if (js.Polygon != null && js.Polygon.Length > 0)
                        {
                            List<PostionItem> temps = new List<PostionItem>();
                            foreach (var p in js.Polygon)
                            {
                                temps.Add(new PostionItem(p.Latitude, p.Longtitude));
                            }
                            item.Polygon = temps.ToArray();
                        }

                        list.Add(item);
                    }
                    items = list.ToArray();
                    //items = JobSitesManagement.GetJobSite(s);
                }
                else
                {
                    items = new JobSiteViewItem[0];
                }
                return items;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object SaveJobSite()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var s = Request.Form["ClientData"];
                    s = HttpUtility.HtmlDecode(s);

                    var js = JsonConvert.DeserializeObject<JobSiteViewItem>(s);
                    JobSiteItem jobsite = new JobSiteItem();
                    Helper.CloneProperty(jobsite, js);
                    jobsite.RadiusUOM = js.Radius_UOM;
                    jobsite.BaseonMachineID = js.BaseOnMachineID;
                    jobsite.Color = js.ColorString;
                    jobsite.JobSiteTypes = string.Join(",", js.Types);
                    if (js.StartDate > Helper.DBMinDateTime)
                        jobsite.StartDate = js.StartDate;
                    if (js.EndDate > Helper.DBMinDateTime)
                        jobsite.EndDate = js.EndDate;
                    if (js.Polygon != null && js.Polygon.Length > 0)
                    {
                        List<Position> list = new List<Position>();
                        foreach (PostionItem pi in js.Polygon)
                        {
                            Position p = new Position(pi.Latitude, pi.Longitude);
                            list.Add(p);
                        }
                        jobsite.Polygon = list.ToArray();
                    }

                    long jobsiteid = CreateClient<JobSiteProvider>().SaveJobSite(SystemParams.CompanyID, jobsite, GetCurrentLoginSession().User.UID);

                    JobSitesManagement.RefreshJobsiteAssets(session.SessionID, jobsiteid);

                    return new string[] { jobsiteid.ToString(), "Saved successfully." };
                }
                else
                {
                    return "Failed";
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private string DeleteJobSite()
        {
            try
            {
                var user = GetCurrentUser();
                if (user != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var s = HttpUtility.HtmlDecode(clientdata[0]);
                    long jsid = Convert.ToInt64(s);
                    var notes = HttpUtility.HtmlDecode(clientdata[1]);

                    CreateClient<JobSiteProvider>().DeleteJobSite(SystemParams.CompanyID, jsid, notes, user.IID);
                    return "OK";
                }
                else
                {
                    return "Failed";
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private string SaveJobSiteMachines()
        {
            try
            {
                if (GetCurrentLoginSession() != null)
                {
                    var s = Request.Form["ClientData"];
                    s = HttpUtility.HtmlDecode(s);
                    var jobsite = JsonConvert.DeserializeObject<JobSiteViewItem>(s);

                    JobSitesManagement.AddMachinesToJobSite(jobsite);

                    return "OK";
                }
                else
                {
                    return "Failed";
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private AssetViewItem[] GetMachines()
        {
            var session = GetCurrentLoginSession();
            if (session != null)
            {
                AssetViewItem[] items = AssetMapViewManagement.GetAssets(session.SessionID, SystemParams.CompanyID, session.User.UID, "", -1, null, false);
                return items;
            }
            return new AssetViewItem[0];
        }

        private object[] GetSelectedAssets()
        {
            var u = GetCurrentUser();
            if (u != null)
            {
                var clientdata = Request.Form["ClientData"].Split((char)170);
                var companyid = HttpUtility.HtmlDecode(clientdata[0]);
                if (string.IsNullOrEmpty(companyid))
                {
                    companyid = SystemParams.CompanyID;
                }
                var jobsiteid = long.Parse(clientdata[1]);
                var jobsites = CreateClient<JobSiteProvider>(companyid).GetAssetsCurrentInJobSite(companyid, jobsiteid);
                return jobsites.Select(i => new
                {
                    i.AssetId,
                    i.OnSite,
                    Name = string.IsNullOrEmpty(i.AssetName2) ? i.AssetName : i.AssetName2,
                    i.VIN,
                    i.MakeName,
                    i.ModelName,
                    i.TypeName
                }).ToArray();
            }
            return new object[0];
        }

        private string AddAssetToJobSite()
        {
            try
            {
                var u = GetCurrentUser();
                if (u != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var companyId = HttpUtility.HtmlDecode(clientdata[0]);
                    if (string.IsNullOrEmpty(companyId))
                    {
                        companyId = SystemParams.CompanyID;
                    }
                    var jobsiteid = long.Parse(clientdata[1]);
                    var machineids = HttpUtility.HtmlDecode(clientdata[2]);

                    var ids = JsonConvert.DeserializeObject<long[]>(machineids);

                    var client = CreateClient<JobSiteProvider>(companyId);
                    foreach (var id in ids)
                    {
                        client.AddAssetToJobSite(companyId, jobsiteid, id, false, u.IID);
                    }
                    return "OK";
                }
                else
                {
                    return "Failed";
                }
            }
            catch (Exception ex)
            {
                SystemParams.WriteLog("error", "JobSitesBasePage.AddAssetToJobSite", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private string RemoveAssetFromJobSite()
        {
            try
            {
                var u = GetCurrentUser();
                if (u != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var companyId = HttpUtility.HtmlDecode(clientdata[0]);
                    if (string.IsNullOrEmpty(companyId))
                    {
                        companyId = SystemParams.CompanyID;
                    }
                    var jobsiteid = long.Parse(clientdata[1]);
                    var machineids = HttpUtility.HtmlDecode(clientdata[2]);

                    var ids = JsonConvert.DeserializeObject<long[]>(machineids);

                    var client = CreateClient<JobSiteProvider>(companyId);
                    foreach (var id in ids)
                    {
                        client.RemoveAssetFromJobSite(companyId, jobsiteid, id, u.IID);
                    }
                    return "OK";
                }
                else
                {
                    return "Failed";
                }
            }
            catch (Exception ex)
            {
                SystemParams.WriteLog("error", "JobSitesBasePage.RemoveAssetFromJobSite", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private string ChangeAssetOnSiteState()
        {
            try
            {
                var u = GetCurrentUser();
                if (u != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var companyId = HttpUtility.HtmlDecode(clientdata[0]);
                    if (string.IsNullOrEmpty(companyId))
                    {
                        companyId = SystemParams.CompanyID;
                    }
                    var jobsiteid = long.Parse(clientdata[1]);
                    var assetid = long.Parse(clientdata[2]);
                    var onsite = (clientdata[3] == "1");

                    CreateClient<JobSiteProvider>(companyId).ChangeAssetOnSiteState(companyId, jobsiteid, assetid, onsite, u.IID);
                    return "OK";
                }
                else
                {
                    return "Failed";
                }
            }
            catch (Exception ex)
            {
                SystemParams.WriteLog("error", "JobSitesBasePage.ChangeAssetOnSiteState", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private MachineViewItem[] GetBindingMachines()
        {
            var session = GetCurrentLoginSession();
            MachineViewItem[] items = JobSitesManagement.GetBindingMachines(session.SessionID, session.User.UID);
            if (items != null)
            {
                items = items.OrderBy((m) => m.ShowName).ToArray();
            }
            return items;
        }

        private MachineTypeItem[] GetMachineTypes()
        {
            MachineTypeItem[] types = JobSitesManagement.GetMachineTypes();
            if (types != null)
            {
                types = types.OrderBy((t) => t.Name).ToArray();
            }
            return types;
        }

        private AvailableMachines GetMachinesByType()
        {
            var session = GetCurrentLoginSession();
            var p = Request.Form["ClientData"];
            p = HttpUtility.HtmlDecode(p);
            var param = JsonConvert.DeserializeObject<JobSiteMahcineQueryItem>(p);

            AvailableMachines machines = JobSitesManagement.GetMachineViewItemByType(session.SessionID, param.JobSiteID, param.MachineTypeID, param.SearchText, session.User.UID);
            return machines;
        }

        private object ImportJobsitePolygon()
        {
            try
            {
                if (GetCurrentLoginSession() != null)
                {
                    string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    string fileName = clientdata;

                    HttpPostedFile uploadFile = null;
                    byte[] buffer = null;
                    if (Request.Files.Count > 0)
                    {
                        uploadFile = Request.Files[0];
                        buffer = ConvertFile2bytes(uploadFile);
                    }

                    return JobSitesManagement.ImportJobsitePolygon(fileName, buffer);
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetJobSiteUsers()
        {
            try
            {
                UserNameInfoItem[] items = null;
                if (GetCurrentLoginSession() != null)
                {
                    var data = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    var jobsiteid = long.Parse(data);
                    var users = CreateClient<JobSiteProvider>().GetJobisteUserNamesList(SystemParams.CompanyID, jobsiteid);

                    List<UserNameInfoItem> list = new List<UserNameInfoItem>();
                    foreach (var user in users)
                    {
                        UserNameInfoItem ui = new UserNameInfoItem();
                        Helper.CloneProperty(ui, user);
                        list.Add(ui);
                    }
                    items = list.ToArray();
                }
                else
                {
                    items = new UserNameInfoItem[0];
                }
                return items;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private class JobSiteMahcineQueryItem
        {
            public string JobSiteID { get; set; }
            public string MachineTypeID { get; set; }
            public string SearchText { get; set; }
        }

    }
}
