using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Foresight.Data;
using System.Web;
using Foresight.Fleet.Services.AssetHealth;
using Foresight.Fleet.Services.Asset;
using Foresight.Fleet.Services.AssetHealth.WorkOrder;
using Foresight.Fleet.Services.Inspection;
using Foresight.Chart.Drawer;
using System.Drawing;
using System.IO;
using Foresight.Chart.Drawer.Contracts;
using System.Net.Mail;

namespace IronIntel.Contractor.Maintenance
{
    public class WorkOrderManager : BusinessBase
    {
        public WorkOrderManager(string dbstr) : base(dbstr)
        {
        }

        public long[] GetOpenWorkOrderID(string machineid)
        {
            const string SQL = "select WORKORDERID from WORKORDER where MACHINEID={0} and STATUS<>'Completed' and and isnull(DELETED,0)=0";
            DataTable tb = GetDataTableBySQL(SQL, machineid);

            List<long> result = new List<long>();
            foreach (DataRow dr in tb.Rows)
            {
                result.Add(FIDbAccess.GetFieldInt(dr[0], 0));
            }

            return result.ToArray();
        }

        public bool CanAccessWorkOrder(string sessionid, string woid, string mid, string useriid)
        {
            const string SQL = "select count(1) from WORKORDER where WORKORDERID={0} and ASSIGNEDTO={1}";

            bool result = true;
            var user = FleetServiceClientHelper.CreateClient<Foresight.Fleet.Services.User.UserQueryClient>(sessionid).GetUserByIID(useriid);
            if ((!user.IsForesightUser) && (user.ContactType == Foresight.Fleet.Services.User.ContactTypes.Technician))
            {
                result = FIDbAccess.GetFieldInt(GetRC1BySQL(SQL, woid, useriid), 0) > 0;
            }
            if (result && user.UserType < Foresight.Fleet.Services.User.UserTypes.Admin)
            {
                long assetid = -1;
                if (!string.IsNullOrEmpty(mid))
                    Int64.TryParse(mid, out assetid);
                else
                {
                    var client = FleetServiceClientHelper.CreateClient<WorkOrderProvider>(sessionid);
                    var workorder = client.GetWorkOrderInfo(SystemParams.CompanyID, Convert.ToInt64(woid));
                    assetid = workorder.AssetID;
                }
                long[] availableAssetsids = FleetServiceClientHelper.CreateClient<AssetQueryClient>(sessionid).GetAvailableAssetsForUsers(SystemParams.CompanyID, useriid);
                if (availableAssetsids != null && !availableAssetsids.Contains(assetid))
                    result = false;
            }
            return result;
        }

        public string[] GetInvoiceNumber(string woid)
        {
            const string SQL = @"select a.INVOICENUMBER from WORKORDER_ALERTS t  left join MAINTENANCELOG a on a.ALERTID=t.ALERTID,MACHINES b 
            where t.WORKORDERID={0} and a.MACHINEID = b.MACHINEID and ISNULL(b.HIDE,0)<>1 and ISNULL(a.INVOICENUMBER,'')<>'' ORDER BY a.ADDEDON DESC";

            DataTable dt = GetDataTableBySQL(SQL, woid);
            if (dt.Rows.Count == 0)
                return new string[0];

            List<string> list = new List<string>();
            foreach (DataRow dr in dt.Rows)
            {
                string num = FIDbAccess.GetFieldString(dr["INVOICENUMBER"], string.Empty);
                if (!string.IsNullOrEmpty(num))
                    list.Add(num);
            }
            return list.ToArray();
        }

        public string[] GetLocations()
        {
            const string SQL = @"select distinct LOCATION from WORKORDER where ISNULL(LOCATION,'')<>''";

            DataTable dt = GetDataTableBySQL(SQL);
            if (dt.Rows.Count == 0)
                return new string[0];

            List<string> list = new List<string>();
            foreach (DataRow dr in dt.Rows)
            {
                string num = FIDbAccess.GetFieldString(dr["LOCATION"], string.Empty);
                if (!string.IsNullOrEmpty(num))
                    list.Add(num);
            }
            return list.ToArray();
        }

        public string[] GetDepartments()
        {
            const string SQL = @"select distinct DEPARTMENT from WORKORDER where ISNULL(DEPARTMENT,'')<>''";

            DataTable dt = GetDataTableBySQL(SQL);
            if (dt.Rows.Count == 0)
                return new string[0];

            List<string> list = new List<string>();
            foreach (DataRow dr in dt.Rows)
            {
                string num = FIDbAccess.GetFieldString(dr["DEPARTMENT"], string.Empty);
                if (!string.IsNullOrEmpty(num))
                    list.Add(num);
            }
            return list.ToArray();
        }


        public string[] GetAdvisors()
        {
            const string SQL = @"select distinct ADVISOR from WORKORDER where ISNULL(ADVISOR,'')<>''";

            DataTable dt = GetDataTableBySQL(SQL);
            if (dt.Rows.Count == 0)
                return new string[0];

            List<string> list = new List<string>();
            foreach (DataRow dr in dt.Rows)
            {
                string num = FIDbAccess.GetFieldString(dr["ADVISOR"], string.Empty);
                if (!string.IsNullOrEmpty(num))
                    list.Add(num);
            }
            return list.ToArray();
        }
        public static string GenerateWorkOrderPrintHtml(string sessionid, string companyid, long woid, string lang)
        {
            var client = FleetServiceClientHelper.CreateClient<WorkOrderProvider>(companyid, sessionid);
            WorkOrderInfo wo = client.GetWorkOrderInfo(companyid, woid);

            StringBuilder str = new StringBuilder();
            str.AppendLine("<H1 style='text-align:center;'>" + SystemParams.GetTextByKey(lang, "P_WORKORDER", "Work Order") + "</H1>");
            string detailstr = SystemParams.GetTextByKey(lang, "P_WO_DETAILFORWORKORDERARELISTEDBELOW", "Details for work order <{0}> are listed below:").Replace("<", "&lt;").Replace(">", "&gt;");
            str.AppendFormat("<div style='font-weight:bold;padding-bottom:5px;'>" + detailstr + "</div>", wo.WorkOrderNumber);
            str.AppendLine("");
            //str.AppendLine("<div class='label' style='text-align:left;'>Work Order Information:</div>");
            str.AppendLine("<div style='padding-left:30px;margin-bottom:36px;'>");

            var aclient = FleetServiceClientHelper.CreateClient<AssetQueryClient>(companyid, sessionid);
            var asset = aclient.GetAssetDetailInfo(companyid, wo.AssetID);
            str.Append(GenerateWorkOrderInfoHtml(asset, wo, lang));
            str.AppendLine("</div>");
            //str.AppendLine("<div class='label' style='text-align:left;'>Segments:</div>");

            WorkOrderSegmentInfo[] segments = client.GetSegments(companyid, woid);

            if (segments != null && segments.Length > 0)
            {
                for (int i = 0; i < segments.Length; i++)
                {
                    var se = segments[i];
                    str.Append(GenerateSegmentHtml(se, i + 1, lang));
                }
            }

            str.Append("<div style='margin-bottom:36px;margin-left:30px;'>");
            str.Append(WorkorderAlertsFormart(woid, lang, sessionid));

            AssetInspectItem[] insplectitems = client.GetWOInspectItems(SystemParams.CompanyID, woid);
            if (insplectitems != null && insplectitems.Length > 0)
            {
                foreach (AssetInspectItem isp in insplectitems)
                {
                    var report = FleetServiceClientHelper.CreateClient<AssetInspectClient>(sessionid).GetInspection(SystemParams.CompanyID, isp.Id);
                    str.Append(GenerateInspectionHtml(report, lang));
                }
            }


            str.Append("</div>");

            return str.ToString();
        }

        private static string GenerateWorkOrderInfoHtml(AssetDetailInfo asset, WorkOrderInfo wo, string lang)
        {
            StringBuilder str = new StringBuilder();
            str.Append("<table>");
            str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_ASSETNAME", "Asset Name") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.Name));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_ASSETNAMECUSTOM", "Asset Name (Custom)") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.Name2));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_VIN", "VIN/SN") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.VIN));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_MAKE", "Make") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.MakeName));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_MODEL", "Model") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.ModelName));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_ASSETTYPE", "Asset Type") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.TypeName));
            str.AppendLine("");
            if (asset.OnRoad)
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_CURRENTODOMETER", "Current Odometer") + "</td><td>{0}</td></tr>", asset.CurrentOdometer == null ? "" : asset.CurrentOdometer.Corrected.ToString("#,##0"));
            else
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_CURRENTHOURS", "Current Hours") + "</td><td>{0}</td></tr>", asset.CurrentHours == null ? "" : asset.CurrentHours.Corrected.ToString("#,##0"));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_CURRJOBSITE", "Current Jobsite") + " </td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.CurrentJobSiteNames));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_CURRLOCATION", "Current Location") + " </td><td>{0}</td></tr>", asset.CurrentLocation == null ? "" : HttpUtility.HtmlEncode(asset.CurrentLocation.Address));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_WORKORDERTYPE", "Work Order Type") + "</td><td>{0}</td></tr>", wo.WorkOrderType);
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPONENT", "Work Order Type") + "</td><td>{0}</td></tr>", wo.Completed);
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_ASSIGNEDTO", "Assigned To") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(wo.AssignedToName));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_STATUS", "Status") + "</td><td>{0}</td></tr>", wo.StatusName);
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_DUEDATE", "Due Date") + "</td><td>{0}</td></tr>", wo.DueDate == null ? "" : wo.DueDate.Value.ToShortDateString());
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_NEXTFOLLOWUPDATE", "Next Follow Up Date") + "</td><td>{0}</td></tr>", wo.NextFollowUpDate == null ? "" : wo.NextFollowUpDate.Value.ToShortDateString());
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_DESCRIPTION", "Description") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(wo.Description).Replace("\n", "<br>"));
            str.AppendLine("");
            if (wo.Completed)
            {
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_METERTYPE", "Meter Type") + "</td><td>{0}</td></tr>", wo.MeterType);
                str.AppendLine("");
                if (string.Compare(wo.MeterType, "HourMeter", true) == 0
                    || string.Compare(wo.MeterType, "Both", true) == 0)
                    str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_HOURMETER", "Hour Meter") + "</td><td>{0}</td></tr>", wo.HourMeter);
                if (string.Compare(wo.MeterType, "Odometer", true) == 0
                    || string.Compare(wo.MeterType, "Both", true) == 0)
                    str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_ODOMETER", "Odometer") + "</td><td>{0}&nbsp;{1}</td></tr>", wo.Odometer, wo.OdometerUnits);
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_WORKORDERTOTALCOST", "Work Order Total Costs ($)") + "</td><td>{0}</td></tr>", wo.WorkOrderTotalCost);
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_OTHERCOST", "Other Cost ($)") + "</td><td>{0}</td></tr>", wo.OtherCost);
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_PARTSCOST", "Parts Cost ($)") + "</td><td>{0}</td></tr>", wo.PartsCost);
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_TRAVELTIMECOST", "Travel Time Cost ($)") + "</td><td>{0}</td></tr>", wo.TravelTimeCost);
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_LABORCOST", "Labor Cost ($)") + "</td><td>{0}</td></tr>", wo.LaborCost);
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_HOURLYRATE", "Hourly Rate") + "</td><td>{0}</td></tr>", wo.HourlyRate);
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_TIMETOCOMPLATEHOURS", "Time To Complete(Hrs)") + "</td><td>{0}</td></tr>", wo.HoursToComplete);
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPLETEDDATE", "Completed Date") + "</td><td>{0}</td></tr>", wo.CompleteDate == null ? "" : wo.CompleteDate.Value.ToShortDateString());
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_INTERNALID", "Internal ID") + "</td><td>{0}</td></tr>", wo.InternalID);
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_INVOICENUMBER", "Invoice Number") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(wo.InvoiceNumber));
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + "Billable" + "</td><td>{0}</td></tr>", wo.Billable ? "Yes" : "No");
                str.AppendLine("");
                str.AppendFormat("<tr><td class='label'>" + "Bill To Job" + "</td><td>{0}</td></tr>", wo.BillToJobName);
                str.AppendLine("");
            }
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_NOTES", "Notes") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(wo.Notes).Replace("\n", "<br>"));
            str.AppendLine("");
            str.AppendFormat("</table>");

            return str.ToString();
        }

        private static string GenerateSegmentHtml(WorkOrderSegmentInfo se, int index, string lang)
        {
            StringBuilder str = new StringBuilder();
            //str.AppendFormat("<div style='margin-bottom:36px;margin-left:30px;{0}'>", (index - 2) % 4 == 0 ? "page-break-after: always;" : "");
            //str.AppendLine("");
            str.AppendLine("<div style='margin-bottom:36px;margin-left:30px;'>");
            str.AppendLine("<table>");
            str.AppendFormat("<tr><td class='label' colspan='2' style='text-align:left;'>" + SystemParams.GetTextByKey(lang, "P_WO_SEGMENT", "Segment") + "&nbsp;{0}</td></tr>", index);
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_USER", "User") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(se.UserName));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_HOURS", "Hours") + "</td><td>{0}</td></tr>", se.Hours);
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_JOBSITE", "Jobsite") + "</td><td>{0}</td></tr>", se.JobsiteName);
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COST", "Cost") + "</td><td>{0}</td></tr>", se.Cost);
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPONENT", "Component") + "</td><td>{0}</td></tr>", se.Component);
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPLETED", "Completed") + "</td><td>{0}</td></tr>", se.Completed ? "Yes" : "No");
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPLETEDDATE", "Completed Date") + "</td><td>{0}</td></tr>", se.CompletedDate == null ? "" : se.CompletedDate.Value.ToShortDateString());
            str.AppendFormat("<tr><td class='label'>" + "Segment Type" + "</td><td>{0}</td></tr>", se.SegmentType);
            str.AppendFormat("<tr><td class='label'>" + "Billable" + "</td><td>{0}</td></tr>", se.Billable ? "Yes" : "No");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_DESCRIPTION", "Description") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(se.Description));
            str.AppendLine("");
            str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_NOTES", "Notes") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(se.Notes).Replace("\n", "<br>"));
            str.AppendLine("");
            str.AppendLine("</table>");
            str.AppendLine("</div>");
            return str.ToString();
        }

        private static string GenerateInspectionHtml(InspectReportInfo report, string lang)
        {
            StringBuilder str = new StringBuilder();
            str.AppendLine("<div style='margin-bottom:36px;'>");
            str.AppendLine("<table>");
            str.AppendFormat("<tr><td class='label' colspan='2' style='text-align:left;'>" + report.Template.Name + "&nbsp;<span style='margin-left:30px;'>" + (report.CommitTimeLocal == DateTime.MinValue ? "" : report.CommitTimeLocal.ToString("M/d/yyyy h:mm tt")) + "</span></td></tr>");
            str.AppendLine("");
            foreach (var page in report.Template.Pages)
            {
                foreach (var section in page.Sections)
                {
                    foreach (var q in section.Questions)
                    {
                        //if (q.VisibleToCustomer)
                        //{
                        str.AppendLine("<tr><td class='label' style='width:170px;'>" + q.DisplayText + "</td>");
                        var span_level = "<span style='float:right;padding-right:3px;'>" + ShowSeverityLevel(lang, (int)q.SeverityLevel) + "</span>";
                        InspectResultItem[] anwers = report.Answers.Where(m => m.QuestionId.ToLower() == q.Id.ToLower()).ToArray();
                        if (anwers != null && anwers.Length > 0)
                        {
                            foreach (var a in anwers)
                            {
                                int[] ids = new int[] { 5, 8, 9, 10, 14, 15 };
                                if (!ids.Contains((int)q.QuestionType) || ((int)q.QuestionType == 15 && q.SubType != 15))
                                {
                                    var result = a.Result;
                                    if (result == null)
                                        result = "";

                                    if ((int)q.QuestionType == 6 && result.IndexOf(' ') >= 0)//Date do not show time
                                        result = result.Split(' ')[0];
                                    if ((int)q.QuestionType == 11//Odometer
                                        || (int)q.QuestionType == 18 //FuelUsed
                                        || ((int)q.QuestionType == 15 && q.SubType == 8)//FuelRecords Odometer
                                        || ((int)q.QuestionType == 15 && q.SubType == 10))//FuelRecords Quantity
                                        result += " " + ConvertUnits(a.Units);

                                    if ((int)q.QuestionType == 17 && q.TextToCompare != null && result.ToLower() != q.TextToCompare.ToLower())  // BarCodeValidate                                            
                                        str.AppendLine("<td><span style='color:red'>" + result + "<span><span style='margin-left:6px'>(" + q.TextToCompare + ")<span>");
                                    else
                                        str.AppendLine("<td>" + result);

                                    str.AppendLine(span_level + "</td>");
                                    break;
                                }
                                else if ((int)q.QuestionType == 5)//YesOrNo
                                {
                                    if (a.SelectedItems != null && a.SelectedItems.Count > 0)
                                    {
                                        span_level = "<span style='float:right;padding-right:3px;'>" + ShowSeverityLevel(lang, (int)a.SelectedItems[0].SeverityLevel) + "</span>";
                                        var label = "<label style='margin-left:5px; '>" + a.SelectedItems[0].Text + "</lable>";
                                        var div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;'></div>";
                                        if (!string.IsNullOrEmpty(a.SelectedItems[0].BackgroundColor))
                                        {
                                            div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;background-color:" + a.SelectedItems[0].BackgroundColor + "'></div>";
                                        }

                                        str.AppendLine("<td>" + div_circle + label + span_level + "</td>");
                                    }
                                }
                                else if ((int)q.QuestionType == 8 || (int)q.QuestionType == 9 || ((int)q.QuestionType == 15 && q.SubType == 6) || ((int)q.QuestionType == 15 && q.SubType == 9))//DropDown、List
                                {
                                    if (q.MultipleSelect)
                                    {
                                        if (a.SelectedItems != null && a.SelectedItems.Count > 0)
                                        {
                                            StringBuilder str1 = new StringBuilder();
                                            str1.AppendLine("<table class='inptable'>");
                                            for (var j = 0; j < a.SelectedItems.Count; j++)
                                            {
                                                str1.AppendLine("<tr>");
                                                span_level = "<span style='float:right;padding-right:3px;'>" + ShowSeverityLevel(lang, (int)a.SelectedItems[j].SeverityLevel) + "</span>";
                                                var label = "<label style='margin-left:5px; '>" + (j + 1) + ". " + a.SelectedItems[j].Text + "</lable>";

                                                var div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;'></div>";
                                                if (!string.IsNullOrEmpty(a.SelectedItems[j].BackgroundColor))
                                                {
                                                    div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;background-color:" + a.SelectedItems[j].BackgroundColor + "'></div>";
                                                }
                                                str1.AppendLine("<td>" + div_circle + label + span_level + "</td>");
                                                str1.AppendLine("</tr>");
                                            }

                                            str1.AppendLine("</table>");
                                            str.AppendLine("<td>" + str1.ToString() + "</td>");
                                        }
                                    }
                                    else
                                    {
                                        if (a.SelectedItems != null && a.SelectedItems.Count > 0)
                                        {
                                            span_level = "<span style='float:right;padding-right:3px;'>" + ShowSeverityLevel(lang, (int)a.SelectedItems[0].SeverityLevel) + "</span>";
                                            var label = "<label style='margin-left:5px; '>" + a.SelectedItems[0].Text + "</lable>";

                                            var div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;'></div>";
                                            if (!string.IsNullOrEmpty(a.SelectedItems[0].BackgroundColor))
                                            {
                                                div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;background-color:" + a.SelectedItems[0].BackgroundColor + "'></div>";
                                            }

                                            str.AppendLine("<td>" + div_circle + label + span_level + "</td>");
                                        }
                                    }
                                }
                                else if ((int)q.QuestionType == 14)//Email (Drop Down)
                                {
                                    if (a.SelectedItems != null && a.SelectedItems.Count > 0)
                                    {
                                        StringBuilder str1 = new StringBuilder();
                                        str1.AppendLine("<table class='inptable'>");
                                        for (var j = 0; j < a.SelectedItems.Count; j++)
                                        {
                                            str1.AppendLine("<tr>");
                                            var label = "<label>" + (j + 1) + ". " + a.SelectedItems[j].Text + "<" + a.SelectedItems[j].Value + "</lable>"; ;
                                            str1.AppendLine("<td>" + label + "</td>");
                                            str1.AppendLine("</tr>");
                                        }
                                        str1.AppendLine("</table>");
                                        str.AppendLine("<td>" + str1.ToString() + "</td>");
                                    }
                                }
                                else if ((int)q.QuestionType == 10 || ((int)q.QuestionType == 15 && q.SubType == 15))//Picture
                                {
                                    StringBuilder str1 = new StringBuilder();
                                    str1.AppendLine("<div style='min-height:80px;overflow:auto;'>");
                                    if (report.Medias != null && report.Medias.Count > 0)
                                    {
                                        for (var j = 0; j < report.Medias.Count; j++)
                                        {
                                            var m = report.Medias[j];
                                            if (m.AnswerId.ToLower() == a.Id.ToLower())
                                            {
                                                string[] pictypes = new string[] { ".mp4", ".mov" };
                                                if (pictypes.Contains(m.FileType.ToLower()))
                                                {
                                                    str1.AppendLine("<div class='media'><span class='video'></span></div>");
                                                }
                                                else
                                                {
                                                    str1.AppendLine("<img class='media' src='" + m.ThumbnailUrl + "'></img>");
                                                }
                                            }
                                        }
                                    }
                                    str1.AppendLine("</div>");

                                    str.AppendLine("<td>" + str1.ToString() + "</td>");
                                }
                                else
                                    str.AppendLine("<td></td>");
                            }
                            str.AppendLine("</tr>");
                            str.AppendLine("");
                        }
                        else
                        {
                            str.AppendLine("<td></td>");
                            str.AppendLine("</tr>");
                            str.AppendLine("");
                        }
                        //}
                    }
                }
            }

            str.AppendLine("</table>");
            str.AppendLine("</div>");
            return str.ToString();
        }

        private static string ConvertUnits(string u)
        {
            switch (u.ToLower())
            {
                case "mile":
                    return "Mile(s)";
                case "kilometre":
                case "kilometer":
                    return "Kilometer";
                case "percent":
                    return "Percent";
                case "gallon":
                case "gal":
                    return "Gallon";
                case "litre":
                    return "Litre";
                default:
                    break;
            }
            return u;
        }

        private static string ShowSeverityLevel(string lang, int level)
        {
            var levertext = SystemParams.GetTextByKey(lang, "P_IPT_SEVERITYLEVEL_COLON", "Severity Level: ");
            if (level == 0)
                levertext = "";
            if (level == 1)
                levertext += SystemParams.GetTextByKey(lang, "P_IPT_SL_LOW", "Low");
            else if (level == 2)
                levertext += SystemParams.GetTextByKey(lang, "P_IPT_SL_MEDIUM", "Medium");
            else if (level == 3)
                levertext += SystemParams.GetTextByKey(lang, "P_IPT_SL_HIGH", "High");
            return levertext;
        }

        public static string WorkorderAlertsFormart(long woid, string lang, string sessionid)
        {
            AlertItems items = GetWorkOrderAlerts(woid, sessionid);
            string EmailFormat = string.Empty;
            if (items != null)
            {
                if (items.DTCAlerts != null && items.DTCAlerts.Length > 0)
                    EmailFormat += AlertsFormat(items.DTCAlerts, SystemParams.GetTextByKey(lang, "P_WO_DTCALERTS", "DTC Alerts"), lang);
                if (items.PMAlerts != null && items.PMAlerts.Length > 0)
                    EmailFormat += AlertsFormat(items.PMAlerts, SystemParams.GetTextByKey(lang, "P_WO_PMALERTS", "PM Alerts"), lang);
                if (items.InspectAlerts != null && items.InspectAlerts.Length > 0)
                    EmailFormat += AlertsFormat(items.InspectAlerts, SystemParams.GetTextByKey(lang, "P_WO_INSPECTALERTS", "Inspect Alerts"), lang);
                if (items.OilAlerts != null && items.OilAlerts.Length > 0)
                    EmailFormat += AlertsFormat(items.OilAlerts, SystemParams.GetTextByKey(lang, "P_WO_OILALERTS", "Oil Alerts"), lang);
            }
            return EmailFormat;
        }

        public static string AlertsFormat(AlertInfo[] alerts, string type, string lang)
        {
            string AlertsFormat = "<table style=\"border:solid 1px #e1dbdb;border-collapse: collapse;margin-bottom:36px;\"><tr>";
            AlertsFormat += "<td colspan=\"6\"><span style=\"font-weight:700;\">{0}</span></td></tr>";

            AlertsFormat += "<tr style=\"height:30px; background-color:#f1f1f1;\">";
            AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_HOURS", "Hours") + "</td>";
            AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_ALERTTYPE", "Alert Type") + "</td>";
            AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_DESCRIPTION", "Description") + "</td>";
            if (string.Compare(type, "PM Alerts", true) == 0)
                AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_SERVICEDESCRIPTION", "Service Description") + "</td>";
            AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_COUNT", "Count") + "</td>";
            AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_LATESTDATETIME", "Latest DateTime") + "</td>";
            AlertsFormat += "</tr>";
            AlertsFormat += "{1}";//Alert Information
            AlertsFormat += "</table>";

            if (alerts != null)
            {
                string tr_data = string.Empty;
                foreach (AlertInfo item in alerts)
                {
                    tr_data += "<tr>";
                    tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.EngineHours + "</td>";
                    tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.AlertType + "</td>";
                    tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.Description + "</td>";
                    if (string.Compare(type, "PM Alerts", true) == 0)
                        tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.ServiceDescription + "</td>";
                    tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.AlertCount + "</td>";
                    tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.AlertLocalTimeStr + "</td>";
                    tr_data += "</tr>";
                }

                return string.Format(AlertsFormat, type, tr_data);
            }
            return string.Empty;
        }

        public static AlertItems GetWorkOrderAlerts(long workorderid, string sessionid)
        {
            AssetAlertItem[] alerts = FleetServiceClientHelper.CreateClient<WorkOrderProvider>(sessionid).GetWorkOrderAlerts(SystemParams.CompanyID, workorderid);

            if (alerts != null)
            {
                AlertItems items = new AlertItems();
                var dtcalerts = new List<AlertInfo>();
                var pmaalerts = new List<AlertInfo>();
                var inspectalerts = new List<AlertInfo>();
                var oilalerts = new List<AlertInfo>();
                Dictionary<string, List<AlertInfo>> pmalertdic = new Dictionary<string, List<AlertInfo>>();
                foreach (AssetAlertItem alertitem in alerts.OrderByDescending(ai => ai.AlertTime))
                {
                    List<AlertInfo> tempList = null;
                    if (alertitem.Category == AssetAlertCategory.PMAlert)
                        tempList = pmaalerts;
                    else if (alertitem.Category == AssetAlertCategory.InspectAlert)
                        tempList = inspectalerts;
                    else if (alertitem.Category == AssetAlertCategory.OilSampleAlert)
                        tempList = oilalerts;
                    else
                        tempList = dtcalerts;

                    var existalert = tempList.FirstOrDefault((ai) => ai.Description == alertitem.Description);
                    if (existalert != null)
                    {
                        existalert.AlertCount++;
                        if (existalert.RepeatedAlerts == null)
                            existalert.RepeatedAlerts = new List<long>();
                        existalert.RepeatedAlerts.Add(alertitem.ID);
                    }
                    else
                    {
                        var a = ConvertAlert(alertitem);
                        a.AlertCount = 1;
                        tempList.Add(a);

                        if (alertitem.Category == AssetAlertCategory.PMAlert)
                        {
                            if (!pmalertdic.ContainsKey(a.ScheduleID))
                                pmalertdic[a.ScheduleID] = new List<AlertInfo>();
                            pmalertdic[a.ScheduleID].Add(a);
                        }
                    }
                }
                items.DTCAlerts = dtcalerts.ToArray();
                items.PMAlerts = pmaalerts.ToArray();
                items.InspectAlerts = inspectalerts.ToArray();
                items.OilAlerts = oilalerts.ToArray();
                items.AllExpectedCost = 0;

                foreach (var dic in pmalertdic)
                {
                    items.AllExpectedCost += dic.Value.Where(m => !m.Recurring).Sum(m => m.ExpectedCost);

                    int minPriority = dic.Value.Select(m => m.Priority).Min();
                    var recalerts = dic.Value.Where(m => m.Priority == minPriority && m.Recurring && m.ExpectedCost > 0);
                    if (recalerts != null && recalerts.Count() > 0)
                        items.AllExpectedCost += recalerts.Sum(m => m.ExpectedCost);
                }

                return items;
            }
            return null;
        }
        private static AlertInfo ConvertAlert(AssetAlertItem alertitem)
        {
            AlertInfo ai = new AlertInfo();
            ai.AlertID = alertitem.ID;
            ai.MachineID = alertitem.AssetID;
            ai.AlertType = alertitem.AlertType;
            ai.Description = alertitem.Description;
            ai.Description = ai.FormatDescription(ai.Description);
            ai.AlertTime_UTC = alertitem.AlertTime;
            ai.AlertLocalTime = alertitem.AlertLocalTime;
            ai.EngineHours = alertitem.EngineHours;
            ai.ServiceDescription = alertitem.ServiceDescription;
            ai.ScheduleID = alertitem.ScheduleID;
            ai.IntervalID = alertitem.IntervalID;
            ai.Recurring = alertitem.Recurring;
            ai.Priority = alertitem.Priority;
            ai.ExpectedCost = alertitem.ExpectedCost;

            return ai;
        }

        public static (string body, KeyValuePair<string, byte[]>[]) GetSurveyReportEmail(SurveyReportInfo report)
        {
            var list = new List<KeyValuePair<string, byte[]>>();

            var sb = new StringBuilder();
            sb.AppendLine("<div>");
            sb.AppendLine($"<div style=\"font-size: 24px; font-weight: bold; text-align: center\">{HttpUtility.HtmlEncode(report.TemplateName)}</div>");
            sb.AppendLine($"<div style=\"font-size: 16px; font-weight: bold; text-align: center\">There are {report.SurveyCount} survey(s) in total.</div>");
            sb.AppendLine("<br/><br/>");
            int count = 0;
            foreach (var q in report.Questions)
            {
                string imgid;
                if (q.QuestionType == SurveyQuestionTypes.Choose)
                {
                    sb.AppendLine($"<div style=\"font-size: 24px; font-weight: bold; padding-left: 10px\">{HttpUtility.HtmlEncode(q.Title)}</div>");
                    imgid = "img" + (++count).ToString("000");
                    sb.AppendLine($"<img src=\"cid:{imgid}\"/>");
                    var chooseBarDrawer = new ColumnChartDrawer
                    {
                        Data = new ChartData
                        {
                            XAxis = q.Values.Select(v => new XValue { Label = v.DisplayText }).ToArray(),
                            XInclinedValue = -45,
                            Series = new[]
                            {
                                new DataSeries
                                {
                                    SeriesType = SeriesType.Column,
                                    Color = Color.FromArgb(0x43, 0x86, 0xd8),
                                    DataPoints = q.Values.Select(v => new DataPoint { Y = v.Count }).ToArray()
                                }
                            }
                        }
                    };
                    var bitmap = new Bitmap(800, 300);
                    var result = chooseBarDrawer.DrawChart(bitmap);
                    var ms = new MemoryStream();
                    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    ms.Flush();
                    list.Add(new KeyValuePair<string, byte[]>(imgid, ms.ToArray()));

                    imgid = "img" + (++count).ToString("000");
                    sb.AppendLine($"<img src=\"cid:{imgid}\"/>");
                    var pieDrawer = new PieChartDrawer
                    {
                        Data = new ChartData
                        {
                            Series = new[]
                            {
                                new DataSeries
                                {
                                    SeriesType = SeriesType.Pie,
                                    DataPoints = q.Values.Select(v => new DataPoint { Name = v.DisplayText, Y = v.Count, DisplayValue = v.Count.ToString() }).ToArray()
                                }
                            },
                            ShowLegend = true
                        }
                    };
                    bitmap = new Bitmap(800, 300);
                    result = pieDrawer.DrawChart(bitmap);
                    ms = new MemoryStream();
                    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    ms.Flush();
                    list.Add(new KeyValuePair<string, byte[]>(imgid, ms.ToArray()));
                }
                else if (q.QuestionType == SurveyQuestionTypes.YesOrNo)
                {
                    sb.AppendLine($"<div style=\"font-size: 24px; font-weight: bold; padding-left: 10px\">{HttpUtility.HtmlEncode(q.Title)}</div>");
                    imgid = "img" + (++count).ToString("000");
                    sb.AppendLine($"<img src=\"cid:{imgid}\"/>");
                    var barDrawer = new BarChartDrawer
                    {
                        Data = new ChartData
                        {
                            XAxis = new[]
                            {
                                new XValue
                                {
                                    Label = string.Empty
                                }
                            },
                            Series = new[]
                            {
                                new DataSeries
                                {
                                    Name = q.Values[0].DisplayText,
                                    SeriesType = SeriesType.Bar,
                                    DataPoints = new[]
                                    {
                                        new DataPoint { Y = q.Values[0].Count }
                                    }
                                },
                                new DataSeries
                                {
                                    Name = q.Values[1].DisplayText,
                                    SeriesType = SeriesType.Bar,
                                    DataPoints = new[]
                                    {
                                        new DataPoint { Y = q.Values[1].Count }
                                    }
                                }
                            },
                            ShowLegend = true
                        }
                    };
                    var bitmap = new Bitmap(700, 220);
                    var result = barDrawer.DrawChart(bitmap);
                    var ms = new MemoryStream();
                    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    ms.Flush();
                    list.Add(new KeyValuePair<string, byte[]>(imgid, ms.ToArray()));
                }
                else if (q.QuestionType == SurveyQuestionTypes.Score)
                {
                    sb.AppendLine($"<div style=\"font-size: 24px; font-weight: bold; padding-left: 10px\">{HttpUtility.HtmlEncode(q.Title)}</div>");
                    imgid = "img" + (++count).ToString("000");
                    sb.AppendLine($"<img src=\"cid:{imgid}\"/>");
                    var chooseBarDrawer = new ColumnChartDrawer
                    {
                        Data = new ChartData
                        {
                            XAxis = q.Values.Select(v => new XValue { Label = v.DisplayText }).ToArray(),
                            XInclinedValue = -45,
                            Series = new[]
                            {
                                new DataSeries
                                {
                                    SeriesType = SeriesType.Column,
                                    Color = Color.FromArgb(0x43, 0x86, 0xd8),
                                    DataPoints = q.Values.Select(v => new DataPoint { Y = v.Count }).ToArray()
                                }
                            }
                        }
                    };
                    var bitmap = new Bitmap(800, 300);
                    var result = chooseBarDrawer.DrawChart(bitmap);
                    var ms = new MemoryStream();
                    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    ms.Flush();
                    list.Add(new KeyValuePair<string, byte[]>(imgid, ms.ToArray()));

                    imgid = "img" + (++count).ToString("000");
                    sb.AppendLine($"<img src=\"cid:{imgid}\"/>");
                    var pieDrawer = new PieChartDrawer
                    {
                        Data = new ChartData
                        {
                            Series = new[]
                            {
                                new DataSeries
                                {
                                    SeriesType = SeriesType.Pie,
                                    DataPoints = q.Values.Select(v => new DataPoint { Name = v.DisplayText, Y = v.Count, DisplayValue = v.Count.ToString() }).ToArray()
                                }
                            },
                            ShowLegend = true
                        }
                    };
                    bitmap = new Bitmap(800, 300);
                    result = pieDrawer.DrawChart(bitmap);
                    ms = new MemoryStream();
                    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    ms.Flush();
                    list.Add(new KeyValuePair<string, byte[]>(imgid, ms.ToArray()));
                }
                else
                {
                    continue;
                }
                sb.AppendLine("<br/><br/>");
            }
            sb.AppendLine("</div>");

            return (sb.ToString(), list.ToArray());
        }
    }

    public class AlertItems
    {
        public AlertInfo[] DTCAlerts { get; set; }
        public AlertInfo[] PMAlerts { get; set; }
        public AlertInfo[] InspectAlerts { get; set; }
        public AlertInfo[] OilAlerts { get; set; }
        public double AllExpectedCost { get; set; }
    }
}