using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Web;
using Newtonsoft.Json;
using IronIntel.Contractor.Users;
using Foresight.Fleet.Services.Customer;
using IronIntel.Contractor.iisitebase;
using Foresight.Fleet.Services.User;
using Foresight.Fleet.Services;

namespace IronIntel.Contractor.Site
{
    public class CommonHttpRequestHandler : IronIntelHttpHandlerBase
    {
        public static byte[] GetCompanyLOGO(string companyid)
        {
            if (string.IsNullOrWhiteSpace(companyid))
            {
                return SystemParams.GetCompanyLOGO(CustomerInfo.FORESIGHT);
            }
            else
            {
                return SystemParams.GetCompanyLOGO(companyid);
            }
        }

        public static byte[] GetForesightLOGOInMainStyle()
        {
            return SystemParams.GetForesightLOGOInMainStyle();
        }

        public static byte[] GetCompanyLocationLOGO(string companyid)
        {
            return SystemParams.GetCompanyLocationLOGO(companyid);
        }
        public static byte[] GetLocationLOGO(string companyid)
        {
            return SystemParams.GetCompanyLocationLOGO(companyid);
        }

        public static byte[] GetCustomerLocationLOGO(int locationid)
        {
            CustomerProvider ic = FleetServiceClientHelper.CreateClient<CustomerProvider>(SystemParams.CompanyID);
            return ic.GetLocationLOGO(SystemParams.CompanyID, locationid, true);
        }

        public CommonHttpRequestHandler(HttpContext context)
            : base(context)
        {
        }

        public override void ProcessRequest()
        {
            string s = ReadTextFromStream(Context.Request.InputStream);
            if (string.IsNullOrWhiteSpace(s))
            {
                Context.Response.StatusCode = 204;
                Context.Response.Write(JsonConvert.SerializeObject(null));
                Context.Response.End();
                return;
            }
            CommonRequestObject req = null;
            try
            {
                req = JsonConvert.DeserializeObject<CommonRequestObject>(s);
            }
            catch
            {
                Context.Response.StatusCode = 400;
                Context.Response.Write(JsonConvert.SerializeObject(null));
                Context.Response.End();
                return;
            }
            if (req == null)
            {
                Context.Response.StatusCode = 204;
                Context.Response.Write(JsonConvert.SerializeObject(null));
                Context.Response.End();
                return;
            }
            ProcessRequest(req);
        }

        private void ProcessRequest(CommonRequestObject req)
        {
            switch (req.Method)
            {
                case CommonRequestMethods.IamAlive:
                    IamAlive();
                    return;
                case CommonRequestMethods.GetAppModules:
                    GetAppModules();
                    return;
                case CommonRequestMethods.GetCurrentLoginName:
                    GetCurrentLoginName();
                    return;
                case CommonRequestMethods.AddLog:
                    AddLog(req.ClientData);
                    return;
                case CommonRequestMethods.GetLanguageResVersion:
                    GetLanguageResVersion(req.ClientData);
                    return;
                case CommonRequestMethods.GetGridLayout:
                    GetGridLayout(req.ClientData);
                    return;
                case CommonRequestMethods.SetGridLayout:
                    SetGridLayout(req.ClientData);
                    return;
                case CommonRequestMethods.DeleteGridLayout:
                    DeleteGridLayout(req.ClientData);
                    return;
                case CommonRequestMethods.GetUserMessages:
                    GetUserMessages(req.ClientData);
                    return;
                case CommonRequestMethods.ReadUserMessages:
                    ReadUserMessages(req.ClientData);
                    return;
                case CommonRequestMethods.DeleteUserMessages:
                    DeleteUserMessages(req.ClientData);
                    return;
                case CommonRequestMethods.GetUnreadCount:
                    GetUnreadCount(req.ClientData);
                    return;
                case CommonRequestMethods.GetCurrentDate:
                    GetCurrentDate();
                    return;
                case CommonRequestMethods.GetGridLayouts:
                    GetGridLayouts(req.ClientData);
                    return;
                default:
                    Context.Response.StatusCode = 204;
                    Context.Response.Write(JsonConvert.SerializeObject(null));
                    Context.Response.End();
                    return;
            }
        }

        private void IamAlive()
        {
            if (LoginSession == null)
            {
                Context.Response.Write(JsonConvert.SerializeObject(null));
                Context.Response.StatusCode = 401;
            }
            else
            {
                Context.Response.Write("\"OK\"");
                Context.Response.StatusCode = 200;
            }
            Context.Response.End();
        }

        private void GetCurrentDate()
        {
            string s = string.Empty;
            if (LoginSession != null)
            {
                DateTime dt = SystemParams.ConvertToUserTimeFromUtc(LoginSession.User, DateTime.UtcNow);
                s = dt.ToString("M/d/yyyy h:mm tt");
            }
            Context.Response.Write(JsonConvert.SerializeObject(s));
            Context.Response.End();
        }

        private void GetAppModules()
        {
            if (LoginSession == null)
            {
                Context.Response.StatusCode = 401;
                Context.Response.Write(JsonConvert.SerializeObject(null));
                Context.Response.End();
                return;
            }
            AppModuleInfo[] items = Acl.GetAvailableAppModuleInfos(LoginSession.User.UID);
            string json = JsonConvert.SerializeObject(items);
            Context.Response.Write(json);
            Context.Response.End();
        }

        private void GetCurrentLoginName()
        {
            string s = LoginSession == null ? string.Empty : LoginSession.User.Name;

            Context.Response.Write(JsonConvert.SerializeObject(s));
            Context.Response.End();
        }

        private void AddLog(string clientdata)
        {
            const char SPLITCHAR = (char)170;

            Context.Response.StatusCode = 200;
            try
            {
                string logininfo = "";
                if (LoginSession != null)
                {
                    logininfo = LoginSession.SessionID;
                    if (LoginSession.User != null)
                        logininfo += "/" + LoginSession.User.ID;
                }
                string[] s = clientdata.Split(new char[] { SPLITCHAR });
                SystemParams.WriteLog_Ext(s[0], s[1], s[2], s[3], logininfo);
                Context.Response.Write("\"OK\"");
            }
            catch
            { }
            Context.Response.End();
        }

        private void GetLanguageResVersion(string clientdata)
        {
            try
            {
                if (string.IsNullOrEmpty(clientdata))
                    clientdata = "en-us";
                string file = clientdata + ".json";
                var path = System.IO.Path.Combine(System.Web.HttpContext.Current.Request.PhysicalApplicationPath, "Languages\\" + file);
                var ticks = System.IO.File.GetLastWriteTimeUtc(path).Ticks;
                string json = JsonConvert.SerializeObject(ticks);
                Context.Response.Write(json);
            }
            catch
            { }
            Context.Response.End();
        }

        private void GetGridLayout(string clientdata)
        {
            try
            {
                string objid = clientdata;
                if (!string.IsNullOrEmpty(objid) && LoginSession != null)
                {
                    var client = FleetServiceClientHelper.CreateClient<UserProfileProvider>(LoginSession.SessionID);
                    var layout = client.GetGridLayout(SystemParams.CompanyID, LoginSession.User.UID, objid);
                    Context.Response.Write(JsonConvert.SerializeObject(layout));
                }
            }
            catch
            { }
            Context.Response.End();
        }

        private void GetGridLayouts(string clientdata)
        {
            try
            {
                string objid = clientdata;
                if (!string.IsNullOrEmpty(objid) && LoginSession != null)
                {
                    var client = FleetServiceClientHelper.CreateClient<UserProfileProvider>(LoginSession.SessionID);
                    UserGridLayoutInfo[] layouts = client.GetGridLayouts(SystemParams.CompanyID, LoginSession.User.UID, objid);
                    Context.Response.Write(JsonConvert.SerializeObject(layouts));
                }
            }
            catch
            { }
            Context.Response.End();
        }

        private void SetGridLayout(string clientdata)
        {
            try
            {
                if (LoginSession != null)
                {
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    var layoutinfo = JsonConvert.DeserializeObject<UserGridLayoutInfo>(ps[0]);
                    if (layoutinfo.IsPublic && LoginSession.User.UserType < Foresight.Fleet.Services.User.UserTypes.Admin)
                        Context.Response.Write("\"-1\"");

                    layoutinfo.UserIID = LoginSession.User.UID;
                    bool overwrite = ps[1] == "1";

                    var client = FleetServiceClientHelper.CreateClient<UserProfileProvider>(LoginSession.SessionID);
                    int r = client.SetGridLayout(SystemParams.CompanyID, layoutinfo, overwrite);
                    Context.Response.Write(JsonConvert.SerializeObject(r));
                }
            }
            catch
            { }
            Context.Response.End();
        }

        private void DeleteGridLayout(string clientdata)
        {
            try
            {
                string layoutid = clientdata;
                if (!string.IsNullOrEmpty(layoutid) && LoginSession != null)
                {
                    var client = FleetServiceClientHelper.CreateClient<UserProfileProvider>(LoginSession.SessionID);
                    //client.DeleteGridLayout(SystemParams.CompanyID, LoginSession.User.UID, int.Parse(objid));
                    client.DeleteGridLayout(SystemParams.CompanyID, int.Parse(layoutid));
                    Context.Response.Write("\"OK\"");
                }
            }
            catch
            { }
            Context.Response.End();
        }

        private void GetUserMessages(string clientdata)
        {
            try
            {
                int startid = 0;
                int.TryParse(clientdata, out startid);
                if (int.TryParse(clientdata, out startid) && LoginSession != null)
                {
                    var client = FleetServiceClientHelper.CreateClient<MessageProvider>(LoginSession.SessionID);
                    var msgs = client.GetMessages(SystemParams.CompanyID, startid);
                    List<MessageInfoClient> msgls = new List<MessageInfoClient>();
                    foreach (var msg in msgs)
                    {
                        MessageInfoClient mc = new MessageInfoClient();
                        Helper.CloneProperty(mc, msg);
                        msgls.Add(mc);
                    }
                    string json = JsonConvert.SerializeObject(msgls);
                    Context.Response.Write(json);
                }
            }
            catch
            { }
            Context.Response.End();
        }

        private void ReadUserMessages(string clientdata)
        {
            try
            {
                long[] msgids = JsonConvert.DeserializeObject<long[]>(clientdata);
                if (msgids.Length > 0 && LoginSession != null)
                {
                    var client = FleetServiceClientHelper.CreateClient<MessageProvider>(LoginSession.SessionID);
                    client.MarkReaded(SystemParams.CompanyID, msgids);
                    Context.Response.Write("\"OK\"");
                }
            }
            catch
            { }
            Context.Response.End();
        }

        private void DeleteUserMessages(string clientdata)
        {
            try
            {
                long[] msgids = JsonConvert.DeserializeObject<long[]>(clientdata);
                if (msgids.Length > 0 && LoginSession != null)
                {
                    var client = FleetServiceClientHelper.CreateClient<MessageProvider>(LoginSession.SessionID);
                    client.DeleteMessage(SystemParams.CompanyID, msgids);
                    Context.Response.Write("\"OK\"");
                }
            }
            catch
            { }
            Context.Response.End();
        }

        private void GetUnreadCount(string clientdata)
        {
            try
            {
                if (LoginSession != null)
                {
                    var client = FleetServiceClientHelper.CreateClient<MessageProvider>(LoginSession.SessionID);
                    int count = client.GetNewMessageNumber(SystemParams.CompanyID);
                    Context.Response.Write(JsonConvert.SerializeObject(count));
                }
            }
            catch
            { }
            Context.Response.End();
        }
    }

    sealed class CommonRequestObject
    {
        public int MethodID { get; set; }
        public string ClientData { get; set; }
        public CommonRequestMethods Method
        {
            get { return (CommonRequestMethods)MethodID; }
        }
    }

    enum CommonRequestMethods
    {
        IamAlive = 0,
        GetAppModules = 1,
        GetCurrentLoginName = 2,
        AddLog = 3,
        GetMachineMapPinItem = 4,
        GetJobSiteMapItem = 5,
        GetLanguageResVersion = 6,
        GetGridLayout = 7,
        SetGridLayout = 8,
        DeleteGridLayout = 9,
        GetUserMessages = 10,
        ReadUserMessages = 11,
        DeleteUserMessages = 12,
        GetUnreadCount = 13,
        GetCurrentDate = 14,
        GetGridLayouts = 15
    }

    public class MessageInfoClient : MessageInfo
    {
        public string CreatedTimeStr { get { return CreatedTime < new DateTime(2000, 1, 1) ? "" : CreatedTime.ToString(); } }
    }
}
