using Foresight.Data;
using Foresight.Fleet.Services;
using Foresight.Fleet.Services.Asset;
using Foresight.Fleet.Services.AssetHealth;
using Foresight.Fleet.Services.Device;
using Foresight.Fleet.Services.JobSite;
using Foresight.Fleet.Services.User;
using IronIntel.Contractor.Machines;
using IronIntel.Contractor.Maintenance;
using IronIntel.Contractor.Users;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Foresight.Standard;

namespace IronIntel.Contractor.Site.Asset
{
    public class ShareAssetBasePage : ContractorBasePage
    {
        protected void ProcessRequest(string method)
        {
            object result = null;
            string methodName = Request.Params["MethodName"];
            try
            {
                if (methodName != null)
                {
                    switch (methodName.ToUpper())
                    {
                        case "GETSHAREWITHCUSTOMERS":
                            result = GetShareWithCustomers();
                            break;
                        case "SETSHAREWITHCUSTOMERS":
                            result = SetShareWithCustomers();
                            break;
                        case "GETASSETSHAREINFOS":
                            result = GetAssetShareInfos();
                            break;
                        case "GETSHAREASSETLIST":
                            result = GetShareAssetList();
                            break;
                        case "SAVESHAREASSET":
                            result = SaveShareAsset();
                            break;
                        case "UNSHAREASSET":
                            result = UnShareAsset();
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                SystemParams.WriteLog("error", "ShareAssetBasePage", ex.Message, ex.ToString());
                throw ex;
            }
            string json = JsonConvert.SerializeObject(result);
            Response.Write(json);
            Response.End();
        }
        private object GetShareWithCustomers()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {

                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    var companyid = ps[0];
                    if (string.IsNullOrEmpty(companyid))
                        companyid = SystemParams.CompanyID;
                    bool sharableonly = Helper.IsTrue(ps[1]);
                    var custs = CreateClient<ShareAssetsProvider>(companyid).GetSharableCustomers(companyid, sharableonly);
                    return custs.OrderBy((c) => c.CustomerName).ToArray();
                }
                else
                    return new MachineItem[0];
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "ShareAssetBasePage.GetShareWithCustomers", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetAssetShareInfos()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    var companyid = ps[0];
                    if (string.IsNullOrEmpty(companyid))
                        companyid = SystemParams.CompanyID;

                    long asstid = -1;
                    long.TryParse(ps[1], out asstid);
                    AssetShareInfo[] assets = CreateClient<ShareAssetsProvider>(companyid).GetAssetShareInfos(companyid, asstid);
                    if (assets == null || assets.Length == 0)
                        return new AssetShareItem[0];

                    List<AssetShareItem> ls = new List<AssetShareItem>();
                    foreach (AssetShareInfo item in assets)
                    {
                        AssetShareItem ai = new AssetShareItem();
                        Helper.CloneProperty(ai, item);
                        ls.Add(ai);
                    }

                    return ls.ToArray();
                }
                else
                    return new AssetShareItem[0];
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "ShareAssetBasePage.GetAssetShareInfos", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetShareAssetList()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {

                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    ShareAssetQueryItem q = JsonConvert.DeserializeObject<ShareAssetQueryItem>(clientdata);
                    if (string.IsNullOrEmpty(q.CustomerId))
                        q.CustomerId = SystemParams.CompanyID;

                    ShareAssetItem[] assets = CreateClient<ShareAssetsProvider>(q.CustomerId).GetShareAssetList(q.CustomerId, q.Shared, q.OnRoad, q.IncludeHidden, q.Filter);
                    List<ShareAssetInfo> ls = new List<ShareAssetInfo>();
                    foreach (ShareAssetItem item in assets)
                    {
                        ShareAssetInfo ai = new ShareAssetInfo();
                        Helper.CloneProperty(ai, item);
                        if (ai.ShareInfo != null)
                        {
                            ai.ChildId = ai.ShareInfo.ChildId;
                            ai.ChildName = ai.ShareInfo.ChildName;
                            ai.StartDate = ai.ShareInfo.StartDate;
                            ai.ExpectedRetrievalDate = ai.ShareInfo.ExpectedRetrievalDate;
                            ai.RetrievalDate = ai.ShareInfo.RetrievalDate;
                        }
                        ls.Add(ai);
                    }

                    return ls.OrderBy(a => a.VIN).ToArray();
                }
                else
                    return new ShareAssetItem[0];
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "ShareAssetBasePage.GetShareAssetList", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object SaveShareAsset()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    var q = JsonConvert.DeserializeObject<SaveShareAssetParam>(clientdata);
                    if (string.IsNullOrEmpty(q.CustomerId))
                        q.CustomerId = SystemParams.CompanyID;

                    DateTime? expected = DateTime.TryParse(q.EndDate, out DateTime dt) ? dt : default(DateTime?);
                    ShareAssetsProvider provider = CreateClient<ShareAssetsProvider>(q.CustomerId);
                    string[] results = new string[q.SharedIds.Length];
                    Task[] tasks = new Task[q.SharedIds.Length];
                    for (var i = 0; i < tasks.Length; i++)
                    {
                        var index = i;
                        var id = q.SharedIds[i];
                        tasks[i] = Task.Run(() =>
                        {
                            try
                            {
                                provider.SetShareAsset(q.CustomerId, new AssetShareInfo
                                {
                                    ChildId = q.SharedWith,
                                    AssetId = id,
                                    ExpectedRetrievalDate = expected,
                                    HideAssetOnThisSite = q.HideAsset
                                });
                            }
                            catch (Exception ex)
                            {
                                results[index] = ex.Message;
                            }
                        });
                    }
                    Task.WaitAll(tasks);
                    return results;
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "ShareAssetBasePage.SaveShareAsset", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object UnShareAsset()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    var q = JsonConvert.DeserializeObject<SaveShareAssetParam>(clientdata);
                    if (string.IsNullOrEmpty(q.CustomerId))
                        q.CustomerId = SystemParams.CompanyID;

                    ShareAssetsProvider provider = CreateClient<ShareAssetsProvider>(q.CustomerId);
                    string[] results = new string[q.SharedIds.Length];
                    Task[] tasks = new Task[q.SharedIds.Length];
                    for (var i = 0; i < tasks.Length; i++)
                    {
                        var index = i;
                        var id = q.SharedIds[i];
                        tasks[i] = Task.Run(() =>
                        {
                            try
                            {
                                provider.UnShareAsset(q.CustomerId, id);
                            }
                            catch (Exception ex)
                            {
                                results[index] = ex.Message;
                            }
                        });
                    }
                    Task.WaitAll(tasks);
                    return results;
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "ShareAssetBasePage.UnShareAsset", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object SetShareWithCustomers()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    var companyid = ps[0];
                    if (string.IsNullOrEmpty(companyid))
                        companyid = SystemParams.CompanyID;

                    string[] ids = JsonConvert.DeserializeObject<string[]>(ps[1]);
                    string[] delids = JsonConvert.DeserializeObject<string[]>(ps[2]);

                    var client = CreateClient<ShareAssetsProvider>(companyid);
                    client.SetSharableCustomers(companyid, ids, true);
                    client.SetSharableCustomers(companyid, delids, false);
                }
                return "";
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "ShareAssetBasePage.SetShareWithCustomers", ex.Message, ex.ToString());
                return ex.Message;
            }
        }


    }
    class ShareAssetInfo : ShareAssetItem
    {
        public string ChildId { get; set; }
        public string ChildName { get; set; }
        public DateTime? StartDate { get; set; }
        public DateTime? ExpectedRetrievalDate { get; set; }
        public DateTime? RetrievalDate { get; set; }
        public string StartDateStr { get { return Helper.IsNullDateTime(StartDate) ? "" : StartDate.Value.ToShortDateString(); } }
        public string ExpectedRetrievalDateStr { get { return Helper.IsNullDateTime(ExpectedRetrievalDate) ? "" : ExpectedRetrievalDate.Value.ToShortDateString(); } }
        public string RetrievalDateStr { get { return Helper.IsNullDateTime(RetrievalDate) ? "" : RetrievalDate.Value.ToShortDateString(); } }
        public double EngineHoursValue => EngineHours == null ? 0 : EngineHours.Value;
    }

    class AssetShareItem : AssetShareInfo
    {
        public string StartDateStr { get { return Helper.IsNullDateTime(StartDate) ? "" : StartDate.Value.ToShortDateString(); } }
        public string ExpectedRetrievalDateStr { get { return Helper.IsNullDateTime(ExpectedRetrievalDate) ? "" : ExpectedRetrievalDate.Value.ToShortDateString(); } }
        public string RetrievalDateStr { get { return Helper.IsNullDateTime(RetrievalDate) ? "" : RetrievalDate.Value.ToShortDateString(); } }

    }

    class ShareAssetQueryItem
    {
        public string CustomerId { get; set; }
        public int Shared { get; set; }
        public int OnRoad { get; set; }
        public bool IncludeHidden { get; set; }
        public string Filter { get; set; }
    }

    class SaveShareAssetParam
    {
        public string CustomerId { get; set; }
        public long[] SharedIds { get; set; }
        public string SharedWith { get; set; }
        public string EndDate { get; set; }
        public bool HideAsset { get; set; }
    }
}
