using Foresight.Data;
using Foresight.ServiceModel;
using IronIntel.Contractor.Machines;
using IronIntel.Contractor.Maintenance;
using IronIntel.Contractor.MapView;
using IronIntel.Contractor.Users;
using IronIntel.Services.Business.Admin;
using IronIntel.Services.Customers;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IronIntel.Contractor.Contact
{
    public class ContactManagement
    {
        public static ContactInfo[] GetContacts(string sessionid, FISqlConnection db = null)
        {
            const string SQL = "select CONTACTID,CONTACTNAME,USERIID,NOTES,CONTACTTYPE,EMAILADDRESS,TEXTADDRESS from CONTACT";

            List<ContactInfo> list = new List<ContactInfo>();
            if (db == null)
                db = SystemParams.GetDbInstance();
            DataTable dt = db.GetDataTableBySQL(SQL);
            if (dt.Rows.Count > 0)
            {
                UserInfo[] users = UserManagement.GetUsers();
                foreach (DataRow dr in dt.Rows)
                {
                    ContactInfo ci = ConvertToContactInfo(dr);
                    if (!string.IsNullOrWhiteSpace(ci.UserIID))
                    {
                        UserInfo ui = users.FirstOrDefault(m => m.IID == ci.UserIID);
                        if (ui != null)
                            ci.UserName = ui.DisplayName;
                    }
                    list.Add(ci);
                }
            }
            return list.ToArray();
        }


        public static void SaveContact(ContactInfo ci, string useriid)
        {
            const string SQL = @"if exists(select 1 from CONTACT where CONTACTID={0}) update CONTACT set CONTACTNAME={1},USERIID={2},NOTES={3},LASTUPDATEDBY={4},
                LASTUPDATEDON = GETUTCDATE(),RECVER = ISNULL(RECVER,0) + 1,CONTACTTYPE={5},EMAILADDRESS={6},TEXTADDRESS={7} where CONTACTID={0} else insert CONTACT(CONTACTID,CONTACTNAME,USERIID, NOTES, ADDEDBY, 
                ADDEDON,LASTUPDATEDBY,LASTUPDATEDON,RECVER,CONTACTTYPE,EMAILADDRESS,TEXTADDRESS) values({0},{1},{2},{3},{4},GETUTCDATE(),{4},GETUTCDATE(),1,{5},{6},{7})";

            const string SQL_C = "select COUNT(1) from CONTACT where CONTACTID!={0} and CONTACTNAME={1}";

            FISqlConnection db = SystemParams.GetDbInstance();
            object obj = db.GetRC1BySQL(SQL_C, ci.ContactID, ci.ContactName);
            if (Convert.ToInt32(obj) > 0)
            {
                throw new Exception("The contact name must be unique.");
            }

            db.ExecSQL(SQL, ci.ContactID, ci.ContactName, ci.UserIID, ci.Notes, useriid, ci.ContactType, ci.EmailAddress, ci.TextAddress);

        }

        public static void DeleteContact(string contactid)
        {
            const string SQL = @"delete from CONTACT where CONTACTID={0}
                    delete from RELATIONSHIP where PRIMARYID = {0} and (RELATIONSHIPTYPEID='MachineContact' or RELATIONSHIPTYPEID='ContactJobsite') ";
            FISqlConnection db = SystemParams.GetDbInstance();
            db.ExecSQL(SQL, contactid);
        }

        public static MaintenanceMachineInfo[] GetContactMachinesByID(string contactid)
        {
            const string SQL = @"select a.RELATEDID as MACHINEID,b.MACHINENAME,b.MACHINENAME2,b.VIN,b.MAKEID,b.MODELID,b.TYPEID,b.HIDE,ISNULL(b.ENGINEHOURS,0) as ENGINEHOURS,
                    ISNULL(b.ODOMETER,0) as ODOMETER,ISNULL(b.ODOMETERUOM,'Mile') AS ODOMETERUOM from RELATIONSHIP a,MACHINES b 
                    where a.RELATEDID=b.MACHINEID and a.RELATIONSHIPTYPEID='MachineContact' and a.REMOVED<>1 and a.PRIMARYID={0}";

            FISqlConnection db = SystemParams.GetDbInstance();
            DataTable tb = db.GetDataTableBySQL(SQL, contactid);
            if (tb.Rows.Count == 0)
            {
                return new MaintenanceMachineInfo[0];
            }
            MachineManagement.RefreshBaseData();
            MachineMake[] makes = MachineManagement.GetMachineMakes();
            MachineModel[] models = MachineManagement.GetMachineModels();
            MachineType[] types = MachineManagement.GetMachineTypes();
            List<MaintenanceMachineInfo> ls = new List<MaintenanceMachineInfo>();
            foreach (DataRow dr in tb.Rows)
            {
                MaintenanceMachineInfo mi = MaintenanceManagement.ConvertToMaintenanceMachineInfo(dr, makes, models, types);
                ls.Add(mi);
            }
            return ls.ToArray();

        }

        public static void SaveContactMachines(string contactid, string contractorid, string[] machineids)
        {
            const string SQL_R = "update RELATIONSHIP set REMOVEDON=GETUTCDATE(),REMOVED=1 where RELATIONSHIPTYPEID='MachineContact' and REMOVED<>1 and PRIMARYID={0}";
            const string SQL = @"if exists(select 1 from RELATIONSHIP where RELATIONSHIPTYPEID='MachineContact' and PRIMARYID={0} and RELATEDID={1}) update RELATIONSHIP
 set REMOVEDON=null,REMOVED=0 where RELATIONSHIPTYPEID='MachineContact' and PRIMARYID={0} and RELATEDID={1} else insert into RELATIONSHIP
 (RELATIONSHIPID,RELATIONSHIPTYPEID,CONTRACTORID,PRIMARYID,RELATEDID,ADDEDON) values({3},'MachineContact',{2},{0},{1},GETUTCDATE())";

            FISqlConnection db = SystemParams.GetDbInstance();
            db.ExecSQL(SQL_R, contactid);

            foreach (var mid in machineids)
            {
                db.ExecSQL(SQL, contactid, mid, contractorid, Guid.NewGuid().ToString());
            }
        }

        public static void SaveMachineContacts(FISqlConnection db, string machineid, string contractorid, string[] contactids)
        {
            const string SQL_R = "update RELATIONSHIP set REMOVEDON=GETUTCDATE(),REMOVED=1 where RELATIONSHIPTYPEID='MachineContact' and REMOVED<>1 and RELATEDID={0}";
            const string SQL = @"if exists(select 1 from RELATIONSHIP where RELATIONSHIPTYPEID='MachineContact' and RELATEDID={0} and PRIMARYID={1}) update RELATIONSHIP
 set REMOVEDON=null,REMOVED=0 where RELATIONSHIPTYPEID='MachineContact' and RELATEDID={0} and PRIMARYID={1} else insert into RELATIONSHIP
 (RELATIONSHIPID,RELATIONSHIPTYPEID,CONTRACTORID,RELATEDID,PRIMARYID,ADDEDON) values({3},'MachineContact',{2},{0},{1},GETUTCDATE())";
            if (db == null)
                db = SystemParams.GetDbInstance();
            db.ExecSQL(SQL_R, machineid);

            foreach (var cid in contactids)
            {
                db.ExecSQL(SQL, machineid, cid, contractorid, Guid.NewGuid().ToString());
            }
        }


        private static ContactInfo ConvertToContactInfo(DataRow dr)
        {
            ContactInfo ci = new ContactInfo();
            ci.ContactID = FIDbAccess.GetFieldString(dr["CONTACTID"], string.Empty);
            ci.ContactName = FIDbAccess.GetFieldString(dr["CONTACTNAME"], string.Empty);
            ci.UserIID = FIDbAccess.GetFieldString(dr["USERIID"], string.Empty);
            ci.Notes = FIDbAccess.GetFieldString(dr["NOTES"], string.Empty);
            ci.ContactType = FIDbAccess.GetFieldString(dr["CONTACTTYPE"], string.Empty);
            ci.EmailAddress = FIDbAccess.GetFieldString(dr["EMAILADDRESS"], string.Empty);
            ci.TextAddress = FIDbAccess.GetFieldString(dr["TEXTADDRESS"], string.Empty);
            return ci;
        }



        public static JobSiteViewItem[] GetContactJobsitesByID(string contactid)
        {
            const string SQL = @"select a.RELATEDID as JOBSITEID,JOBSITENAME,LATITUDE,LONGITUDE,RADIUS,RADUIS_UOM,b.CONTRACTORID,COLOR,NOTES,STARTDATE,ENDDATE,POLYGON,BASEONMACHINEID from RELATIONSHIP a,JOBSITES b 
                    where a.RELATIONSHIPTYPEID='ContactJobsite' and a.REMOVED<>1 and a.RELATEDID=b.JOBSITEID and a.PRIMARYID={0}";

            FISqlConnection db = SystemParams.GetDbInstance();
            DataTable tb = db.GetDataTableBySQL(SQL, contactid);
            if (tb.Rows.Count == 0)
            {
                return new JobSiteViewItem[0];
            }
            List<JobSiteViewItem> ls = new List<JobSiteViewItem>();
            foreach (DataRow dr in tb.Rows)
            {
                JobSiteViewItem js = ConvertToJobSiteViewItem(dr);
                ls.Add(js);
            }
            return ls.ToArray();

        }

        public static void SaveContactJobsites(string contactid, string contractorid, string[] jobsiteids)
        {
            const string SQL_R = "update RELATIONSHIP set REMOVEDON=GETUTCDATE(),REMOVED=1 where RELATIONSHIPTYPEID='ContactJobsite' and REMOVED<>1 and PRIMARYID={0}";
            const string SQL = @"if exists(select 1 from RELATIONSHIP where RELATIONSHIPTYPEID='ContactJobsite' and PRIMARYID={0} and RELATEDID={1}) update RELATIONSHIP
 set REMOVEDON=null,REMOVED=0 where RELATIONSHIPTYPEID='ContactJobsite' and PRIMARYID={0} and RELATEDID={1} else insert into RELATIONSHIP
 (RELATIONSHIPID,RELATIONSHIPTYPEID,CONTRACTORID,PRIMARYID,RELATEDID,ADDEDON) values({3},'ContactJobsite',{2},{0},{1},GETUTCDATE())";

            FISqlConnection db = SystemParams.GetDbInstance();
            db.ExecSQL(SQL_R, contactid);

            foreach (var mid in jobsiteids)
            {
                db.ExecSQL(SQL, contactid, mid, contractorid, Guid.NewGuid().ToString());
            }
        }
        private static JobSiteViewItem ConvertToJobSiteViewItem(DataRow dr)
        {
            JobSiteViewItem js = new JobSiteViewItem();
            long JobSiteId = FIDbAccess.GetFieldInt(dr["JOBSITEID"], 0);
            js.ID = FIDbAccess.GetFieldInt(dr["JOBSITEID"], 0);
            js.Name = FIDbAccess.GetFieldString(dr["JOBSITENAME"], string.Empty);
            js.Latitude = FIDbAccess.GetFieldDouble(dr["LATITUDE"], 0);
            js.Longitude = FIDbAccess.GetFieldDouble(dr["LONGITUDE"], 0);
            js.Radius = FIDbAccess.GetFieldDouble(dr["RADIUS"], 0);
            js.Radius_UOM = FIDbAccess.GetFieldString(dr["RADUIS_UOM"], string.Empty);
            if (string.IsNullOrWhiteSpace(js.Radius_UOM))
                js.Radius_UOM = "Mile";
            js.ContractorID = FIDbAccess.GetFieldString(dr["CONTRACTORID"], string.Empty);
            //js.ColorString = FIDbAccess.GetFieldString(dr["COLOR"], string.Empty);
            //System.Drawing.Color color = System.Drawing.Color.Orange;
            //try
            //{
            //    color = System.Drawing.ColorTranslator.FromHtml(js.ColorString);
            //}
            //catch
            //{
            //}
            //js.Color = new IIColor() { Alpha = color.A, Red = color.R, Green = color.G, Blue = color.B };

            js.Notes = FIDbAccess.GetFieldString(dr["NOTES"], string.Empty);
            js.StartDate = FIDbAccess.GetFieldDateTime(dr["STARTDATE"], DateTime.MinValue);
            js.EndDate = FIDbAccess.GetFieldDateTime(dr["ENDDATE"], DateTime.MinValue);
            js.BaseOnMachineID = FIDbAccess.GetFieldInt(dr["BASEONMACHINEID"], 0);
            return js;
        }

        /// <summary>
        /// 获取机器Contact和机器的对应关系
        /// </summary>
        /// <returns></returns>
        public static Dictionary<int, List<string>> GetContactMachines(FISqlConnection db)
        {
            const string SQL_C = "select PRIMARYID,RELATEDID from RELATIONSHIP where RELATIONSHIPTYPEID='MachineContact' and REMOVED<>1";

            Dictionary<int, List<string>> result = new Dictionary<int, List<string>>();
            if (db == null)
                db = SystemParams.GetDbInstance();
            DataTable tb = db.GetDataTableBySQL(SQL_C);

            foreach (DataRow dr in tb.Rows)
            {
                int machineid = FIDbAccess.GetFieldInt(dr["RELATEDID"], 0);
                string contactid = FIDbAccess.GetFieldString(dr["PRIMARYID"], "");
                if (!result.ContainsKey(machineid))
                    result[machineid] = new List<string>();
                result[machineid].Add(contactid);
            }
            return result;
        }

        /// <summary>
        /// 获取机器对应的ContactID
        /// </summary>
        /// <returns></returns>
        public static string[] GetContactByMachineID(FISqlConnection db, long machineid)
        {
            const string SQL_C = "select PRIMARYID from RELATIONSHIP where RELATIONSHIPTYPEID='MachineContact' and REMOVED<>1 and RELATEDID={0}";

            Dictionary<int, List<string>> result = new Dictionary<int, List<string>>();
            if (db == null)
                db = SystemParams.GetDbInstance();
            DataTable tb = db.GetDataTableBySQL(SQL_C, machineid);
            if (tb.Rows.Count <= 0)
                return new string[0];

            List<string> list = new List<string>();
            foreach (DataRow dr in tb.Rows)
            {
                string contactid = FIDbAccess.GetFieldString(dr["PRIMARYID"], "");
                list.Add(contactid);
            }
            return list.ToArray();
        }


        public static ContactInfo[] GetContactByAssetID(long assetid, string companyid)
        {
            const string SQL = @"select CONTACTID,CONTACTNAME,USERIID,NOTES,CONTACTTYPE,EMAILADDRESS,TEXTADDRESS from CONTACT where
            CONTACTID in(select PRIMARYID from RELATIONSHIP where RELATIONSHIPTYPEID='MachineContact' and REMOVED<>1 and RELATEDID={0} union all
            select rs.PRIMARYID from RELATIONSHIP rs left join JOBSITEMACHINES jm on rs.RELATEDID=jm.JOBSITEID where rs.RELATIONSHIPTYPEID='ContactJobsite' and rs.REMOVED<>1 and jm.MACHINEID={0})";

            FISqlConnection db = null;
            if (string.IsNullOrWhiteSpace(companyid))
                db = SystemParams.GetDbInstance();
            else
            {
                string connetionstring = SystemParams.GetDbStringByCompany(companyid);
                db = new FISqlConnection(connetionstring);
            }

            List<ContactInfo> list = new List<ContactInfo>();
            DataTable dt = db.GetDataTableBySQL(SQL, assetid);
            if (dt.Rows.Count > 0)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    ContactInfo ci = ConvertToContactInfo(dr);
                    list.Add(ci);
                }
            }
            return list.ToArray();
        }
    }
}