using Foresight.Fleet.Services.Asset;
using Foresight.Fleet.Services.MapView;
using Foresight.Fleet.Services.User;
using IronIntel.Contractor.Machines;
using IronIntel.Contractor.Maintenance;
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 SingleAssetViewBasePage : ContractorBasePage
    {
        protected void ProcessRequest(string method)
        {
            object result = null;
            try
            {
                string methodName = Request.Params["MethodName"];
                if (methodName != null)
                {
                    switch (methodName.ToUpper())
                    {
                        case "GETASSETDETAILINFO":
                            result = GetAssetDetailInfo();
                            break;
                        case "GETPMINFO":
                            result = GetPMInfo();
                            break;
                        case "GETASSETRENTAL":
                            result = GetAssetRental();
                            break;
                        case "GETASSETDETAILWORKSPACECONFIG":
                            result = GetAssetDetailWorkspaceConfig();
                            break;
                        case "GETASSETONOFFTIMELINE":
                            result = GetAssetOnOffTimeline();
                            break;
                        case "GETASSETSONOFFTIMELINE":
                            result = GetAssetsOnOffTimeline();
                            break;
                        case "ISCALAMPPRIMARYLOCATION":
                            result = IsCalampPrimaryLocation();
                            break;
                        case "GETASSETEXTINFO":
                            result = GetAssetExtInfo();
                            break;
                        case "GETASSETMAPATTACHMENTS":
                            result = GetAssetMapAttachments();
                            break;
                        case "GETNOWFORMATDATE":
                            result = GetNowFormatDate();
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                SystemParams.WriteLog("error", "SingleAssetViewBasePage", ex.Message, ex.ToString());
                throw ex;
            }
            string json = JsonConvert.SerializeObject(result);
            Response.Write(json);
            Response.End();
        }

        private object GetAssetDetailInfo()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var custid = HttpUtility.HtmlDecode(clientdata[0]);
                    var assetidstr = HttpUtility.HtmlDecode(clientdata[1]);
                    long assetid = -1;
                    long.TryParse(assetidstr, out assetid);
                    if (string.IsNullOrWhiteSpace(custid))
                        custid = SystemParams.CompanyID;

                    AssetDetailInfo info = CreateClient<AssetQueryClient>(custid).GetAssetDetailInfo(custid, assetid);

                    AssetDetailItem assetdetail = new AssetDetailItem();
                    Helper.CloneProperty(assetdetail, info);
                    assetdetail.MoveStatus = info.MoveStatus;
                    if (info.CurrentLocation != null)
                    {
                        assetdetail.CurrentLocation = new AssetAddressItem();
                        Helper.CloneProperty(assetdetail.CurrentLocation, info.CurrentLocation);
                    }
                    if (info.CurrentHours != null)
                    {
                        assetdetail.CurrentHours = new AssetEngineHoursItem();
                        Helper.CloneProperty(assetdetail.CurrentHours, info.CurrentHours);
                    }
                    if (info.CurrentIdleHours != null)
                    {
                        assetdetail.CurrentIdleHours = new AssetIdlehoursItem();
                        Helper.CloneProperty(assetdetail.CurrentIdleHours, info.CurrentIdleHours);
                    }
                    if (info.CurrentOdometer != null)
                    {
                        assetdetail.CurrentOdometer = new AssetOdometerItem();
                        Helper.CloneProperty(assetdetail.CurrentOdometer, info.CurrentOdometer);
                    }

                    return assetdetail;
                }
                else
                    return new AssetDetailItem();
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetAssetExtInfo()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var custid = HttpUtility.HtmlDecode(clientdata[0]);
                    var assetidstr = HttpUtility.HtmlDecode(clientdata[1]);
                    var viewalertstypes = HttpUtility.HtmlDecode(clientdata[2]);
                    long assetid = -1;
                    long.TryParse(assetidstr, out assetid);
                    if (string.IsNullOrWhiteSpace(custid))
                        custid = SystemParams.CompanyID;

                    MachineDeviceBasePage.AssetExtItem info = new MachineDeviceBasePage.AssetExtItem();
                    AssetExtInfo ext = CreateClient<AssetQueryClient>(custid).GetAssetExtInfo(custid, assetid, viewalertstypes);
                    Helper.CloneProperty(info, ext);

                    if (info.InspectReportItem != null)
                    {
                        var temp = new InspectReportInfo();
                        Helper.CloneProperty(temp, info.InspectReportItem);
                        info.InspectReportItem = temp;
                        info.InspectReportItem.CommitTime = info.InspectReportItem.LocalCommitTime == null ? DateTime.MinValue : info.InspectReportItem.LocalCommitTime.Value;
                        info.InspectReportItem.LastUpdatedTime = info.InspectReportItem.LocalLastUpdatedTime == null ? DateTime.MinValue : info.InspectReportItem.LocalLastUpdatedTime.Value;
                    }
                    if (info.Alerts != null)
                    {
                        List<MachineDeviceBasePage.AssetAlertItem> list = new List<MachineDeviceBasePage.AssetAlertItem>();
                        foreach (var a in info.Alerts)
                        {
                            MachineDeviceBasePage.AssetAlertItem ai = new MachineDeviceBasePage.AssetAlertItem();
                            Helper.CloneProperty(ai, a);
                            if (ai.Description.IndexOf("\r\n") > 0)
                                ai.Description = ai.Description.Substring(0, ai.Description.IndexOf("\r\n"));
                            if (ai.Description.IndexOf("\n") > 0)
                                ai.Description = ai.Description.Substring(0, ai.Description.IndexOf("\n"));
                            list.Add(ai);
                        }
                        info.AlertItems = list.ToArray();
                    }
                    if (info.PMPlanInfos != null)
                    {
                        List<MachineDeviceBasePage.AssetPMPlanItem> list = new List<MachineDeviceBasePage.AssetPMPlanItem>();
                        foreach (var a in info.PMPlanInfos)
                        {
                            MachineDeviceBasePage.AssetPMPlanItem ai = new MachineDeviceBasePage.AssetPMPlanItem();
                            Helper.CloneProperty(ai, a);

                            list.Add(ai);
                        }
                        info.PMPlanItems = list.ToArray();
                    }

                    if (info.AssetStatus != null)
                    {
                        List<MachineDeviceBasePage.AssetStatusItem> list = new List<MachineDeviceBasePage.AssetStatusItem>();
                        foreach (var a in info.AssetStatus)
                        {
                            MachineDeviceBasePage.AssetStatusItem ai = new MachineDeviceBasePage.AssetStatusItem();
                            Helper.CloneProperty(ai, a);

                            list.Add(ai);
                        }
                        info.AssetStatusItems = list.ToArray();
                    }
                    if (info.AssetMaintenanceRecord != null)
                    {
                        info.MaintenanceRecordItem = new MachineDeviceBasePage.AssetMaintenanceRecordItem();
                        Helper.CloneProperty(info.MaintenanceRecordItem, info.AssetMaintenanceRecord);
                    }
                    return info;
                }
                else
                    return new AssetExtInfo();
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "SingleAssetViewBasePage.GetAssetExtInfo", ex.Message, ex.ToString());
                return ex.Message;
            }
        }
        private object GetPMInfo()
        {
            try
            {
                var session = GetCurrentLoginSession();
                PMInfo ominfo = new PMInfo();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var custid = HttpUtility.HtmlDecode(clientdata[0]);
                    var assetidstr = HttpUtility.HtmlDecode(clientdata[1]);
                    long assetid = -1;
                    long.TryParse(assetidstr, out assetid);
                    if (string.IsNullOrWhiteSpace(custid))
                        custid = SystemParams.CompanyID;

                    var client = CreateClient<AssetQueryClient>(custid);
                    var names = client.GetAssetPMScheduleNames(custid, assetid);
                    ominfo.ScheduleNames = string.Join(", ", names);
                    ominfo.AlertMessages = client.GetAssetPMAlertMessagess(custid, assetid);
                }
                return ominfo;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object GetAssetRental()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var custid = HttpUtility.HtmlDecode(clientdata[0]);
                    var assetidstr = HttpUtility.HtmlDecode(clientdata[1]);
                    long assetid = -1;
                    long.TryParse(assetidstr, out assetid);
                    if (string.IsNullOrWhiteSpace(custid))
                        custid = SystemParams.CompanyID;

                    var temp = CreateClient<AssetQueryClient>(custid).GetAssetCurrentRentalSimpleInfo(custid, assetid);
                    if (temp != null)
                    {
                        MachineRentalInfo rental = new MachineRentalInfo();
                        rental.RentalID = temp.ID;
                        rental.ProjectReturnDate = temp.PrjReturnDate;
                        rental.RentalRate = (decimal)temp.Rate;
                        rental.RentalDate = temp.RentalDate;
                        rental.ReturnDate = temp.ReturnDate;
                        rental.Term = temp.Term;
                        rental.TermUnit = temp.TermUnit;
                        return rental;
                    }
                    return null;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetAssetOnOffTimeline()
        {
            try
            {
                var clientdata = Request.Form["ClientData"].Split((char)170);
                var companyid = HttpUtility.HtmlDecode(clientdata[0]);
                if (string.IsNullOrEmpty(companyid))
                {
                    companyid = SystemParams.CompanyID;
                }
                var assetid = long.Parse(clientdata[1]);
                var date = DateTime.Parse(clientdata[2]);
                Foresight.Fleet.Services.SystemUtil util = CreateClient<Foresight.Fleet.Services.SystemUtil>();
                return CreateClient<AssetLocationQueryClient>(companyid).GetAssetOnOffTimeline(companyid, assetid, date).Select(s =>
                {
                    double off;
                    if (s.Off != null)
                    {
                        off = s.Off.Value.TimeOfDay.TotalSeconds;
                    }
                    else
                    {
                        var now = util.GetCustomerDateTimeNow(companyid);
                        if (now.Date == date.Date && (s.On == null || now > s.On.Value))
                        {
                            off = now.TimeOfDay.TotalSeconds;
                        }
                        else
                        {
                            // 23:59:59
                            off = 24 * 60 * 60 - 1;
                        }
                    }
                    return new OnOffItem
                    {
                        HasOn = s.On != null,
                        Start = s.On?.TimeOfDay.TotalSeconds ?? 0,
                        HasOff = s.Off != null,
                        End = off
                    };
                });
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetAssetsOnOffTimeline()
        {
            try
            {
                var clientdata = Request.Form["ClientData"].Split((char)170);
                var companyid = HttpUtility.HtmlDecode(clientdata[0]);
                if (string.IsNullOrEmpty(companyid))
                {
                    companyid = SystemParams.CompanyID;
                }
                var assetids = clientdata[1].Split(',').Select(i => long.Parse(i)).ToArray();
                var date = DateTime.Parse(clientdata[2]).Date;
                Foresight.Fleet.Services.SystemUtil util = CreateClient<Foresight.Fleet.Services.SystemUtil>();
                return CreateClient<AssetLocationQueryClient>(companyid).GetAssetsOnOffTimeline(companyid, assetids, date).Select(it => new OnOffItems
                {
                    AssetId = it.AssetId,
                    Items = it.Events.Select(s =>
                    {
                        double off;
                        if (s.Off != null)
                        {
                            off = s.Off.Value.TimeOfDay.TotalSeconds;
                        }
                        else
                        {
                            var now = util.GetCustomerDateTimeNow(companyid);
                            if (now.Date == date.Date && (s.On == null || now > s.On.Value))
                            {
                                off = now.TimeOfDay.TotalSeconds;
                            }
                            else
                            {
                                // 23:59:59.999
                                off = 24 * 60 * 60 - .001;
                            }
                        }
                        return new OnOffItem
                        {
                            HasOn = s.On != null,
                            Start = s.On?.TimeOfDay.TotalSeconds ?? 0,
                            HasOff = s.Off != null,
                            End = off
                        };
                    }).ToArray()
                });
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private string IsCalampPrimaryLocation()
        {
            try
            {
                var clientdata = Request.Form["ClientData"].Split((char)170);
                var companyid = HttpUtility.HtmlDecode(clientdata[0]);
                if (string.IsNullOrEmpty(companyid))
                {
                    companyid = SystemParams.CompanyID;
                }
                var assetid = long.Parse(clientdata[1]);
                return CreateClient<AssetQueryClient>(companyid).IsCalampPrimaryLocation(companyid, assetid) ? "1" : "0";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetAssetDetailWorkspaceConfig()
        {
            return MachineDetailWorkspace.GetConfig();
        }

        private object GetAssetMapAttachments()
        {
            var session = GetCurrentLoginSession();
            if (session != null)
            {
                var clientdata = Context.Request.Params["ClientData"];
                string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                string companyid = ps[0];
                if (string.IsNullOrEmpty(companyid))
                    companyid = SystemParams.CompanyID;
                long assetid = 0;
                if (!long.TryParse(ps[1], out assetid))
                    return null;

                var client = FleetServiceClientHelper.CreateClient<MapViewQueryClient>(companyid, session.SessionID);
                return client.GetAssetDocumentsOnMap(companyid, assetid);
            }
            return null;
        }
        private string GetNowFormatDate()
        {
            var session = GetCurrentLoginSession();
            if (session != null)
            {
                return SystemParams.ConvertToUserTimeFromUtc(session.User, DateTime.UtcNow).ToString("M/d/yyyy h:mm:ss tt");
            }
            return "";
        }


        class AssetDetailItem
        {
            public long ID { get; set; }
            public string Name { get; set; }
            public string Name2 { get; set; }
            public string VIN { get; set; }
            public int MakeID { get; set; }
            public int TypeID { get; set; }
            public int ModelID { get; set; }
            public string MakeName { get; set; }
            public string ModelName { get; set; }
            public string TypeName { get; set; }
            public int MakeYear { get; set; }
            public string Description { get; set; }
            public string AquisitionType { get; set; }
            public string CostCenter { get; set; }
            public DateTime? DateAddedUtc { get; set; }
            public string DateAddedUtcStr { get { return DateAddedUtc.ToString(); } }
            public DateTime? DateAddedLocal { get; set; }
            public string DateAddedLocalStr { get { return DateAddedLocal.ToString(); } }
            public string GroupNames { get; set; }
            public string CurrentJobSiteNames { get; set; }
            public string LastForeman { get; set; }
            public string AssetIconUrl { get; set; }
            public string MapViewIconUrl { get; set; }
            public bool OnRoad { get; set; }
            public bool TelematicsEnabled { get; set; }
            public double? FuelLevel { get; set; }
            public string CurrentOperator { get; set; }
            public AssetShareStatus ShareStatus { get; set; }

            public AssetAddressItem CurrentLocation { get; set; }
            public AssetEngineHoursItem CurrentHours { get; set; }
            public AssetIdlehoursItem CurrentIdleHours { get; set; }
            public AssetOdometerItem CurrentOdometer { get; set; }
            public string DisplayName
            {
                get
                {
                    //DisplayName取值顺序为Name2,Name,VIN,ID用于前端显示
                    string name = Name2;
                    if (string.IsNullOrWhiteSpace(name))
                        name = Name;
                    if (string.IsNullOrWhiteSpace(name))
                        name = VIN;
                    if (string.IsNullOrWhiteSpace(name))
                        name = ID.ToString();
                    return name;
                }
            }

            public AssetMoveStatus MoveStatus { get; set; }
        }

        public class InspectReportInfo : Foresight.Fleet.Services.Inspection.InspectReportItem
        {
            public string CommitTimeStr { get { return (CommitTime == null || CommitTime == DateTime.MinValue) ? "" : CommitTime.ToString("M/d/yyyy"); } }
            public string LastUpdatedTimeStr { get { return (LastUpdatedTime == null || LastUpdatedTime == DateTime.MinValue) ? "" : LastUpdatedTime.ToString("M/d/yyyy"); } }
        }

        class AssetAttributeItemBase
        {
            public long AssetID { get; set; }
            public DateTime AsofTime { get; set; }//utc time
            public string AsofTimeStr { get { return AsofTime < Helper.DBMinDateTime ? "" : AsofTime.ToString(); } }
            public DateTime AsofTimeLocal { get; set; }//AsOftime的用户本地时间表示
            public string AsofTimeLocalStr { get { return AsofTimeLocal < Helper.DBMinDateTime ? "" : AsofTimeLocal.ToString(); } }
            public bool AsofTimeOverdue { get { return AsofTime < DateTime.Now.ToUniversalTime().AddDays(-3); } }
            public string DataSource { get; set; }
            public string SubSource { get; set; }
            public string DataSourceName { get; set; }
            public bool IsRed
            {
                get
                {
                    bool result = false;
                    if (AsofTimeLocal != null && AsofTimeLocal != DateTime.MinValue
                        && AsofTimeLocal < DateTime.Now.AddDays(-3))
                        result = true;

                    return result;
                }
            }
        }

        class AssetAddressItem : AssetAttributeItemBase
        {
            public double Latitude { get; set; }
            public double Longitude { get; set; }
            public string Street { get; set; }
            public string City { get; set; }
            public string State { get; set; }
            public string PostalCode { get; set; }
            public string Country { get; set; }
            public bool IsPrimary { get; set; }
            public string Address { get; set; }

            public string EventType { get; set; }
            public string SpeedLimitUnits { get; set; }
            public string SpeedUnits { get; set; }
            public int Heading { get; set; }
            public double PostedSpeedLimit { get; set; }
            public double Speed { get; set; }
            public string MsgUID { get; set; }
        }

        class AssetEngineHoursItem : AssetAttributeItemBase
        {
            public double Hours { get; set; }

            private double _Corrected;
            public double Corrected
            {
                get
                {
                    return _Corrected;
                }
                set
                {
                    value = value > 0 ? value : 0;
                    _Corrected = Math.Round(value, 2);
                }
            }
            public bool IsPrimary { get; set; }
        }
        class AssetIdlehoursItem : AssetAttributeItemBase
        {
            private double _Hours;
            public double Hours
            {
                get
                {
                    return _Hours;
                }
                set
                {
                    value = value > 0 ? value : 0;
                    _Hours = Math.Round(value, 2);
                }
            }
            public bool IsPrimary { get; set; }
        }
        class AssetOdometerItem : AssetAttributeItemBase
        {
            public string UOM { get; set; }

            private double _Odometer;
            public double Odometer
            {
                get
                {
                    return _Odometer;
                }
                set
                {
                    value = value > 0 ? value : 0;
                    _Odometer = Math.Round(value, 2);
                }
            }
            private double _Corrected;
            public double Corrected
            {
                get
                {
                    return _Corrected;
                }
                set
                {
                    value = value > 0 ? value : 0;
                    _Corrected = Math.Round(value, 2);
                }
            }
            public bool IsPrimary { get; set; }
        }

        class PMInfo
        {
            public string ScheduleNames { get; set; }
            public string[] AlertMessages { get; set; }
        }

        class OnOffItem
        {
            public bool HasOn { get; set; }
            public bool HasOff { get; set; }
            public double Start { get; set; }
            public double End { get; set; }
        }

        class OnOffItems
        {
            public long AssetId { get; set; }
            public OnOffItem[] Items { get; set; }
        }
    }
}
