using Ease.Core.DataAccess;
using Ease.Core.Model;
using Ease.Core.Utility;
using HRM.BO;
using System;
using System.Collections.Generic;

namespace HRM.DA
{
    public class EmployeeStatusService : ServiceTemplate, IEmployeeStatusService
    {
        public EmployeeStatusService()
        {
        }

        private void MapComponentObject(EmployeeStatus.EmpStatusComponent oEmployeeStatusComponent, DataReader oReader)
        {
            base.SetObjectID(oEmployeeStatusComponent, oReader.GetInt32("EmployeeStatusComponentID").Value);
            oEmployeeStatusComponent.ComponentType =(EnumLifeCycleComponent) oReader.GetInt32("EmployeeStatusComponent").Value;
            oEmployeeStatusComponent.StatusID = oReader.GetInt32("StatusID", 0);
            this.SetObjectState(oEmployeeStatusComponent, Ease.Core.ObjectState.Saved);
        }

        private void MapComponentObject(EmployeeStatus.EmployeeStatusComponentUser oEmployeeStatusComponentUser,
            DataReader oReader)
        {
            base.SetObjectID(oEmployeeStatusComponentUser, oReader.GetInt32("EmployeeStatusComponentUserID").Value);
            oEmployeeStatusComponentUser.EmployeeStatusID = oReader.GetInt32("EmployeeStatusID").Value;
            oEmployeeStatusComponentUser.UserID = oReader.GetInt32("UserID").Value;
            this.SetObjectState(oEmployeeStatusComponentUser, Ease.Core.ObjectState.Saved);
        }

        private EmployeeStatus.EmpStatusComponent CreateComponentObject(DataReader oReader)
        {
            EmployeeStatus.EmpStatusComponent item = new EmployeeStatus.EmpStatusComponent();
            MapComponentObject(item, oReader);
            return item;
        }

        private EmployeeStatus.EmployeeStatusComponentUser CreateEmpStatusComponentUserObject(DataReader oReader)
        {
            EmployeeStatus.EmployeeStatusComponentUser item = new EmployeeStatus.EmployeeStatusComponentUser();
            MapComponentObject(item, oReader);
            return item;
        }

        private List<EmployeeStatus.EmpStatusComponent> CreateComponent(DataReader dr)
        {
            List<EmployeeStatus.EmpStatusComponent> oEmpSpouses = new List<EmployeeStatus.EmpStatusComponent>();
            while (dr.Read())
            {
                EmployeeStatus.EmpStatusComponent item = CreateComponentObject(dr);
                oEmpSpouses.Add(item);
            }

            return oEmpSpouses;
        }

        private List<EmployeeStatus.EmployeeStatusComponentUser> CreateEmpStatusComponentUser(DataReader dr)
        {
            List<EmployeeStatus.EmployeeStatusComponentUser> oEmpStatusComponentUsers =
                new List<EmployeeStatus.EmployeeStatusComponentUser>();
            while (dr.Read())
            {
                EmployeeStatus.EmployeeStatusComponentUser item = CreateEmpStatusComponentUserObject(dr);
                oEmpStatusComponentUsers.Add(item);
            }

            return oEmpStatusComponentUsers;
        }

        private void MapObject(EmployeeStatus oEmployeeStatus, DataReader oReader)
        {
            base.SetObjectID(oEmployeeStatus, oReader.GetInt32("StatusID").Value);
            oEmployeeStatus.EmpStatus = (EnumEmployeeStatus)oReader.GetInt32("EmpStatus").Value;
            oEmployeeStatus.Description = oReader.GetString("Description");
            oEmployeeStatus.ContinueOwnPartPF = oReader.GetBoolean("ContinueOwnPartPF").Value;
            oEmployeeStatus.ContinueCmpPartPF = oReader.GetBoolean("ContinueCmpPartPF").Value;
            oEmployeeStatus.ContinueGratuity = oReader.GetBoolean("ContinueGratuity").Value;
            //oEmployeeStatus.IsJoining = oReader.GetBoolean("IsJoining").Value;
            oEmployeeStatus.IsJoining = oReader.GetBoolean("IsJoining", true);
            //oEmployeeStatus.IsPromotion = oReader.GetBoolean("IsPromotion").Value;
            oEmployeeStatus.IsPromotion = oReader.GetBoolean("IsPromotion", true);
            oEmployeeStatus.IsTransferReceived = oReader.GetBoolean("IsTransferReceived").Value;
            oEmployeeStatus.Sequence = oReader.GetInt32("SequenceNo").Value;
            oEmployeeStatus.Status = (EnumStatus)oReader.GetInt32("Status").Value;
            oEmployeeStatus.CreatedBy = oReader.GetInt32("CreatedBy", 0);
            oEmployeeStatus.CreatedDate = oReader.GetDateTime("CreatedDate").HasValue
                ? oReader.GetDateTime("CreatedDate").Value
                : DateTime.Now;
            //oEmployeeStatus.ModifiedBy = oReader.GetID("ModifiedBy").IsUnassigned ? ID.FromInteger(0) : oReader.GetID("ModifiedBy");
            //oEmployeeStatus.ModifiedDate = oReader.GetDateTime("ModifiedDate").HasValue ? oReader.GetDateTime("ModifiedDate").Value : DateTime.Now;
            this.SetObjectState(oEmployeeStatus, Ease.Core.ObjectState.Saved);
        }

        protected override T CreateObject<T>(DataReader oReader)
        {
            EmployeeStatus oEmployeeStatus = new EmployeeStatus();
            MapObject(oEmployeeStatus, oReader);
            return oEmployeeStatus as T;
        }

        protected EmployeeStatus CreateObject(DataReader oReader)
        {
            EmployeeStatus oEmployeeStatus = new EmployeeStatus();
            MapObject(oEmployeeStatus, oReader);
            return oEmployeeStatus;
        }

        #region Service implementation

        public EmployeeStatus GetRelatedData(EmployeeStatus EmployeeStatus, TransactionContext tc)
        {
            EmployeeStatus.EmployeeStatusComponents = GetChild(EmployeeStatus.ID, tc);
            EmployeeStatus.EmpStatusComponentUsers = GetEmpStatusComponentUser(tc, EmployeeStatus.ID);

            return EmployeeStatus;
        }

        public List<EmployeeStatus.EmpStatusComponent> GetChild(int parentID, TransactionContext tc)
        {
            List<EmployeeStatus.EmpStatusComponent> employeeStatusCopms = new List<EmployeeStatus.EmpStatusComponent>();

            try
            {
                DataReader dataReader = new DataReader(EmployeeStatusDA.GetChild(tc, parentID));
                employeeStatusCopms = this.CreateComponent(dataReader);
                dataReader.Close();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }


            return employeeStatusCopms;
        }

        public EmployeeStatus Get(int id, TransactionContext tc)
        {
            EmployeeStatus oEmployeeStatus = null;
            try
            {
                DataReader oreader = new DataReader(EmployeeStatusDA.Get(tc, id));
                if (oreader.Read())
                {
                    oEmployeeStatus = this.CreateObject<EmployeeStatus>(oreader);
                }

                oreader.Close();
                if (oEmployeeStatus != null)
                {
                    GetRelatedData(oEmployeeStatus, tc);

                }
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeStatus;
        }

        public List<EmployeeStatus> GetByUserID(int userid)
        {
            List<EmployeeStatus> employeeStatuses = new List<EmployeeStatus>();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr = new DataReader(EmployeeStatusDA.GetByUserID(tc, userid));
                employeeStatuses = this.CreateObjects<EmployeeStatus>(dr);
                dr.Close();
                if (employeeStatuses != null && employeeStatuses.Count > 0)
                {
                    dr = new DataReader(EmployeeStatusDA.GetallComponenet(tc));
                    List<EmployeeStatus.EmpStatusComponent> ocms = this.CreateComponent(dr);
                    employeeStatuses.ForEach(x =>
                    {
                        x.EmployeeStatusComponents = ocms.FindAll(c => c.StatusID == x.ID);
                    });
                    dr.Close();
                }

            

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeStatuses;
        }


        public EmployeeStatus Get(int id)
        {
            EmployeeStatus oEmployeeStatus = null;

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader oreader = new DataReader(EmployeeStatusDA.Get(tc, id));
                if (oreader.Read())
                {
                    oEmployeeStatus = this.CreateObject<EmployeeStatus>(oreader);
                }

                oreader.Close();
                if (oEmployeeStatus != null)
                    GetRelatedData(oEmployeeStatus, tc);

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oEmployeeStatus;
        }


        public List<EmployeeStatus> Get(TransactionContext tc, EnumStatus status)
        {
            List<EmployeeStatus> employeeStatuses = new List<EmployeeStatus>();
            try
            {
                DataReader dr = new DataReader(EmployeeStatusDA.Get(tc, status));
                employeeStatuses = this.CreateObjects<EmployeeStatus>(dr);
                dr.Close();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return employeeStatuses;
        }


        public List<EmployeeStatus> Get(EnumStatus status)
        {
            List<EmployeeStatus> employeeStatuses = new List<EmployeeStatus>();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr = new DataReader(EmployeeStatusDA.Get(tc, status));
                employeeStatuses = this.CreateObjects<EmployeeStatus>(dr);
                dr.Close();
                if(employeeStatuses!=null & employeeStatuses.Count >0)
                {
                    if (employeeStatuses != null && employeeStatuses.Count > 0)
                    {
                        dr = new DataReader(EmployeeStatusDA.GetallComponenet(tc));
                        List<EmployeeStatus.EmpStatusComponent> ocms = this.CreateComponent(dr);
                        employeeStatuses.ForEach(x =>
                        {
                            x.EmployeeStatusComponents = ocms.FindAll(c => c.StatusID == x.ID);
                        });
                        dr.Close();

                        dr = new DataReader(EmployeeStatusDA.GetAllEmpStatusComponentUser(tc));
                        List<EmployeeStatus.EmployeeStatusComponentUser> ourc = this.CreateEmpStatusComponentUser(dr);
                        employeeStatuses.ForEach(x =>
                        {
                            x.EmpStatusComponentUsers = ourc.FindAll(c => c.EmployeeStatusID == x.ID);
                        });
                        dr.Close();

                    }


                }

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }
            return employeeStatuses;
        }

        public List<EmployeeStatus> Get(EnumStatus status, EnumLifeCycleComponent sComponentStatus)
        {
            List<EmployeeStatus> employeeStatuses = new List<EmployeeStatus>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr = new DataReader(EmployeeStatusDA.Get(tc, status, sComponentStatus));
                employeeStatuses = this.CreateObjects<EmployeeStatus>(dr);
                dr.Close();

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }


            return employeeStatuses;
        }

        public List<EmployeeStatus> GetByEmpStatus(EnumStatus status, EnumEmployeeStatus empStatus)
        {
            List<EmployeeStatus> employeeStatuses = new List<EmployeeStatus>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dr = new DataReader(EmployeeStatusDA.GetByEmpStatus(tc, status, empStatus));
                employeeStatuses = this.CreateObjects<EmployeeStatus>(dr);
                dr.Close();

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }


            return employeeStatuses;
        }

        public List<EmployeeStatus> Get()
        {
            List<EmployeeStatus> employeeStatuses = new List<EmployeeStatus>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                DataReader dr = new DataReader(EmployeeStatusDA.Get(tc));
                employeeStatuses = this.CreateObjects<EmployeeStatus>(dr);
                dr.Close();

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }


            return employeeStatuses;
        }

        public List<EmployeeStatus.EmpStatusComponent> GetChild(int parentID)
        {
            List<EmployeeStatus.EmpStatusComponent> employeeStatusCopms = new List<EmployeeStatus.EmpStatusComponent>();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dataReader = new DataReader(EmployeeStatusDA.GetChild(tc, parentID));
                employeeStatusCopms = this.CreateComponent(dataReader);
                dataReader.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }


            return employeeStatusCopms;
        }




        public List<EmployeeStatus.EmployeeStatusComponentUser> GetEmpStatusComponentUser(int parentID)
        {
            List<EmployeeStatus.EmployeeStatusComponentUser> employeeStatusCopmUsers =
                new List<EmployeeStatus.EmployeeStatusComponentUser>();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                DataReader dataReader = new DataReader(EmployeeStatusDA.GetEmpStatusComponentUser(tc, parentID));
                employeeStatusCopmUsers = this.CreateEmpStatusComponentUser(dataReader);
                dataReader.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }


            return employeeStatusCopmUsers;
        }

        public List<EmployeeStatus.EmployeeStatusComponentUser> GetEmpStatusComponentUser(TransactionContext tc,
            int parentID)
        {
            List<EmployeeStatus.EmployeeStatusComponentUser> employeeStatusCopmUsers =
                new List<EmployeeStatus.EmployeeStatusComponentUser>();
            try
            {
                DataReader dataReader = new DataReader(EmployeeStatusDA.GetEmpStatusComponentUser(tc, parentID));
                employeeStatusCopmUsers = this.CreateEmpStatusComponentUser(dataReader);
                dataReader.Close();
            }
            catch (Exception e)
            {
                #region Handle Exception;

                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }


            return employeeStatusCopmUsers;
        }

        public int Save(EmployeeStatus oEmployeeStatus)
        {
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);
                if (oEmployeeStatus.IsNew)
                {
                    int id = tc.GenerateID("EmployeeStatus", "StatusID");
                    base.SetObjectID(oEmployeeStatus, id);

                    EmployeeStatusDA.Insert(tc, oEmployeeStatus);
                    GradeSalaryChangeTypeService oItem = new GradeSalaryChangeTypeService();
                }
                else
                {
                    EmployeeStatusDA.Update(tc, oEmployeeStatus);
                }

                tc.End();
                return oEmployeeStatus.ID;
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }


        public int SaveStatus(EmployeeStatus oEmployeeStatus)
        {
            TransactionContext tc = null;
            try
            {
                int Id = 0;
                tc = TransactionContext.Begin(true);
                if (oEmployeeStatus.IsNew)
                {
                    Id = tc.GenerateID("EmployeeStatus", "StatusID");
                    base.SetObjectID(oEmployeeStatus, Id);
                    EmployeeStatusDA.Insert(tc, oEmployeeStatus);


                }
                else
                {
                    Id = oEmployeeStatus.ID;
                    EmployeeStatusDA.Update(tc, oEmployeeStatus);
                    EmployeeStatusDA.DeleteChild(tc, oEmployeeStatus.ID);
                    EmployeeStatusDA.DeleteEmpStatusComponentUser(tc, oEmployeeStatus.ID);
                }


                if (oEmployeeStatus.EmployeeStatusComponents.FindIndex(x => x.ComponentType == EnumLifeCycleComponent.Grade) != -1
         || oEmployeeStatus.EmployeeStatusComponents.FindIndex(x => x.ComponentType == EnumLifeCycleComponent.Basic_salary) != -1)
                {
                    GradeSalaryChangeType osrv = new GradeSalaryChangeTypeService().Get(tc, oEmployeeStatus.ID);
                    if (osrv == null)
                    {
                        GradeSalaryChangeType gtype = new GradeSalaryChangeType();
                        gtype.ID = oEmployeeStatus.ID;
                        gtype.Name = oEmployeeStatus.EmpStatusName;
                        gtype.CreatedBy = oEmployeeStatus.CreatedBy;
                        gtype.CreatedDate = oEmployeeStatus.CreatedDate;
                        gtype.EffectType = EnumGradeSalaryEffect.Both;
                        gtype.Sequence = oEmployeeStatus.Sequence;
                        GradeSalaryChangeTypeDA.Insert(tc, gtype);
                    }
                }
                foreach (EmployeeStatus.EmpStatusComponent statusComponent in oEmployeeStatus.EmployeeStatusComponents)
                {
                    int cId = tc.GenerateID("EmployeeStatusComponent", "EmployeeStatusComponentID");
                    base.SetObjectID(statusComponent, cId);
                    statusComponent.StatusID = Id;
                    EmployeeStatusDA.Insert(tc, statusComponent);
                }
                
                foreach (EmployeeStatus.EmployeeStatusComponentUser item in oEmployeeStatus.EmpStatusComponentUsers)
                {
                    int uId = tc.GenerateID("EmployeeStatusComponentUser", "EmployeeStatusComponentUserID");
                    base.SetObjectID(item, uId);
                    item.EmployeeStatusID = (Id);
                    EmployeeStatusDA.Insert(tc, item);
                }

                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();

                ExceptionLog.Write(e);

                throw new ServiceException(e.Message, e);

                #endregion
            }
            return oEmployeeStatus.ID;
        }

        private void UpdateParent(int oldId, int currentID, List<SystemConfigaration> configurations)
        {
            foreach (SystemConfigaration config in configurations)
            {
                if (config.ParentID == oldId)
                {
                    config.ParentID = currentID;
                }
            }
        }


        public void Delete(int id)
        {
            TransactionContext tc = null;
            try
            {
                EmployeeStatus oest = Get(id);
                // oest.GradeSalaryChangeType = (new GradeSalaryChangeTypeService()).Get(id);
                tc = TransactionContext.Begin(true);
                EmployeeStatusDA.DeleteChild(tc, id);
                EmployeeStatusDA.DeleteEmpStatusComponentUser(tc, id);
                EmployeeStatusDA.Delete(tc, id);
                //if (oest.GradeSalaryChangeType != null)
                //{
                //    GradeSalaryChangeTypeService oItem = new GradeSalaryChangeTypeService();
                //    oItem.Delete(tc, id);
                //}
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        #endregion
    }
}