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


namespace HRM.DA.Fund
{
    public class MemberService : ServiceTemplate, IMemberService
    {
        #region Private Function And Declaration

        public MemberService()
        {
        }

        private void MapObject(Member oMember, DataReader dr)
        {
            base.SetObjectID(oMember, dr.GetInt32("MemberID").Value);
            oMember.EmpCode = dr.GetString("EmpCode");
            oMember.Name = dr.GetString("Name");
            oMember.ProjectID = dr.GetInt32("ProjectID").Value;
            oMember.MembershipNo = dr.GetString("MembershipNo");
            oMember.MembershipDate = dr.GetDateTime("MembershipDate");
            oMember.FinalSettlementDate = dr.GetDateTime("FinalSettlementDate");
            oMember.DOB = dr.GetDateTime("DOB").Value;
            oMember.DOJ = dr.GetDateTime("DOJ").HasValue ? dr.GetDateTime("DOJ").Value : DateTime.MinValue;
            oMember.DOL = dr.GetDateTime("DOL");
            oMember.CompanyName = dr.GetString("CompanyName");
            oMember.Status = (EnumEmpStatus)dr.GetInt16("Status").Value;
            oMember.IsSentToFAS = dr.GetBoolean("IsSentToFAS").Value;
            oMember.CreatedBy = dr.GetInt32("CreatedBy").Value;
            oMember.CreatedDate = dr.GetDateTime("CreatedDate").Value;
            oMember.ModifiedBy = dr.GetInt32("ModifiedBy", 0);
            oMember.ModifiedDate = dr.GetDateTime("ModifiedDate");
            oMember.SignumID = dr.GetString("SignumID");
            oMember.Email = dr.GetString("Email") == null ? "" : dr.GetString("Email");
            oMember.IsProfitPartner = dr.GetBoolean("IsProfitPartner").Value;

            base.SetObjectState(oMember, ObjectState.Saved);
        }

        protected override T CreateObject<T>(DataReader dr)
        {
            Member item = new Member();
            MapObject(item, dr);
            return item as T;
        }

        private Member CreateObject(DataReader dr)
        {
            Member oMember = new Member();
            MapObject(oMember, dr);
            return oMember;
        }

        private List<Member> CreateObjects(IDataReader dr)
        {
            List<Member> oMembers = new List<Member>();
            DataReader oreader = new DataReader(dr);
            while (dr.Read())
            {
                Member Item = CreateObject(oreader);
                oMembers.Add(Item);
            }

            return oMembers;
        }

        #endregion

        public Member Get(int id)
        {
            Member oMember = new Member();

            #region Cache Header

            oMember = new Member();
            if (oMember != null)
                return oMember;

            #endregion

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                IDataReader oreader = MemberDA.Get(tc, id);
                DataReader dr = new DataReader(oreader);
                if (oreader.Read())
                {
                    oMember = CreateObject<Member>(dr);
                }

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

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException("Failed to Get Member", e);

                #endregion
            }

            #region Cache Footer

            #endregion

            return oMember;
        }

        public List<Member> GetLiveMemberOn(DateTime liveOnDate, int fundtypeid)
        {
            List<Member> Members = new List<Member>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                IDataReader dr = MemberDA.GetLiveMember(tc, liveOnDate, fundtypeid);
                Members = CreateObjects(dr);
                dr.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException("Failed to Get Member ", e);

                #endregion
            }

            return Members;
        }

        public List<Member> GetAuditLiveMemberOn(DateTime YearEndLastDate, DateTime ActualAuditDate, int fundtypeid)
        {
            List<Member> Members = new List<Member>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                IDataReader dr = MemberDA.GetAuditLiveMemberOn(tc, YearEndLastDate, ActualAuditDate, fundtypeid);
                Members = CreateObjects(dr);
                dr.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException("Failed to Get Member ", e);

                #endregion
            }

            return Members;
        }

        public List<Member> GetSettledMember(DateTime fromDate, DateTime toDate, int fundtypeid)
        {
            List<Member> Members = new List<Member>();

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                IDataReader dr = MemberDA.GetSettledMember(tc, fromDate, toDate, fundtypeid);
                Members = CreateObjects(dr);
                dr.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException("Failed to Get Member ", e);

                #endregion
            }

            return Members;
        }

        public List<Member> Getbyfundtype(int fundtypeid)
        {
            List<Member> Members = new List<Member>();

            #region Cache Header

            if (Members != null)
                return Members;

            #endregion

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                IDataReader dr = MemberDA.Get(tc, fundtypeid);
                Members = CreateObjects(dr);
                dr.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException("Failed to Get Member ", e);

                #endregion
            }

            #region Cache Footer

            #endregion

            return Members;
        }

        public List<Member> GetByStatus(int statusInInt)
        {
            List<Member> Members = new List<Member>();

            #region Cache Header

            if (Members != null)
                return Members;

            #endregion

            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                IDataReader dr = MemberDA.Get(tc, statusInInt);
                Members = CreateObjects(dr);
                dr.Close();
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException("Failed to Get Member ", e);

                #endregion
            }

            #region Cache Footer

            #endregion

            return Members;
        }

        public List<Member> Get(bool isHasMail)
        {
            List<Member> Members = new List<Member>();
            TransactionContext tc = null;
            try
            {
                string subQuery = string.Empty;
                if (isHasMail)
                {
                    subQuery = SQLParser.TagSQL(subQuery) + SQLParser.MakeSQL(" Email IS Not Null");
                }
                else
                {
                    subQuery = SQLParser.TagSQL(subQuery) + SQLParser.MakeSQL(" Email IS Null");
                }

                tc = TransactionContext.Begin(true);
                IDataReader dr = MemberDA.GetMemberList(tc, subQuery);
                Members = CreateObjects(dr);
                dr.Close();

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

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException("Failed to Get Member ", e);

                #endregion
            }

            return Members;
        }

        public List<Member> GetMembers(DateTime fromDate, DateTime ToDate)
        {
            List<Member> Members = new List<Member>();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);
                IDataReader dr = MemberDA.GetMembers(tc, fromDate, ToDate);
                Members = CreateObjects(dr);
                dr.Close();

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

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException("Failed to Get Member ", e);

                #endregion
            }

            return Members;
        }


        internal Member Get(TransactionContext tc, string code, int fundtypeid)
        {
            #region Cache Header

            Member member = new Member();

            if (member != null)
                return member;

            #endregion

            try
            {
                DataReader dr = new DataReader(MemberDA.Get(tc, code, fundtypeid));
                if (dr.Read())
                {
                    member = this.CreateObject<Member>(dr);
                }

                dr.Close();
            }
            catch (Exception e)
            {
                throw e;
            }

            #region Cache Footer

            #endregion

            return member;
        }

        internal Member Get(TransactionContext tc, int memberID)
        {
            #region Cache Header

            Member member = new Member();

            if (member != null)
                return member;

            #endregion

            try
            {
                DataReader dr = new DataReader(MemberDA.Get(tc, memberID));
                if (dr.Read())
                {
                    member = this.CreateObject<Member>(dr);
                }

                dr.Close();
            }
            catch (Exception e)
            {
                throw e;
            }

            #region Cache Footer

            #endregion

            return member;
        }

        public Member Get(string code, int fundtypeid)
        {
            #region Cache Header

            Member member = new Member();

            if (member != null)
                return member;

            #endregion

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

                DataReader dr = new DataReader(MemberDA.Get(tc, code, fundtypeid));
                if (dr.Read())
                {
                    member = this.CreateObject<Member>(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
            }

            #region Cache Footer

            #endregion

            return member;
        }

        public List<Member> GetMemberList(string nameOp, string name, EnumEmpStatus status, string membershipOperator,
            DateTime membershipFromDate, DateTime membershipToDate, string joiningOperator, DateTime joiningFromDate,
            DateTime joiningToDate, string sEmpNo, int projectID)
        {
            List<Member> Members = new List<Member>();
            TransactionContext tc = null;
            try
            {
                string subQuery = string.Empty;
                if (nameOp != null && nameOp != string.Empty)
                {
                    if (nameOp == "=")
                        subQuery = SQLParser.TagSQL(subQuery) + SQLParser.MakeSQL(" Name " + nameOp + " %s", name);
                    else
                        subQuery = SQLParser.TagSQL(subQuery) +
                                   SQLParser.MakeSQL(" Name " + nameOp + " %s", "%" + name + "%");
                }

                if (status != EnumEmpStatus.All)
                {
                    subQuery = SQLParser.TagSQL(subQuery) + SQLParser.MakeSQL(" Status = %n", status);
                }

                if (membershipOperator != string.Empty && membershipOperator != "None" && membershipOperator != "" &&
                    membershipOperator != "<>")
                {
                    subQuery = SQLParser.TagSQL(subQuery) +
                               SQLParser.MakeSQL(" MembershipDate " + membershipOperator + " %d ", membershipFromDate);
                }

                if (membershipOperator == "<>")
                {
                    subQuery = SQLParser.TagSQL(subQuery) + SQLParser.MakeSQL(" MembershipDate Between %d AND %d ",
                        membershipFromDate, membershipToDate);
                }

                if (joiningOperator != string.Empty && joiningOperator != "None" && joiningOperator != "" &&
                    joiningOperator != "<>")
                {
                    subQuery = SQLParser.TagSQL(subQuery) +
                               SQLParser.MakeSQL(" DOJ " + joiningOperator + " %d ", joiningFromDate);
                }

                if (joiningOperator == "<>")
                {
                    subQuery = SQLParser.TagSQL(subQuery) +
                               SQLParser.MakeSQL(" DOJ Between %d AND %d ", joiningFromDate, joiningToDate);
                }

                if (projectID >= 1)
                {
                    subQuery = SQLParser.TagSQL(subQuery) + SQLParser.MakeSQL(" projectID= %n", projectID);
                }

                if (sEmpNo != "")
                {
                    subQuery = SQLParser.TagSQL(subQuery) + SQLParser.MakeSQL(" EmpCode= %s", sEmpNo);
                }

                tc = TransactionContext.Begin(true);
                IDataReader dr = MemberDA.GetMemberList(tc, subQuery);
                Members = CreateObjects(dr);
                dr.Close();

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

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

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return Members;
        }

        public bool IsExist(string code)
        {
            bool exists = false;
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);
                exists = MemberDA.IsExist(tc, code);
                tc.End();
            }
            catch (Exception e)
            {
                throw new ServiceException("Failed to Check by code" + e.Message, e);
            }

            return exists;
        }

        public void Delete(int id)
        {
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);
                MemberDA.Delete(tc, id);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

                if (tc != null)
                    tc.HandleError();
                ExceptionLog.Write(e);
                throw new ServiceException("Failed to Delete Member", e);

                #endregion
            }
        }

        #region Insert

        public int Save(Member Member)
        {
            Member oMember = new Member();
            oMember = Member;
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin(true);

                if (oMember.IsNew)
                {
                    int id = tc.GenerateID("Member", "MemberID");
                    base.SetObjectID(oMember, (id));
                    MemberDA.Insert(tc, oMember);
                }
                else
                {
                    MemberDA.Update(tc, oMember);
                }

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

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

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return oMember.ID;
        }

        public void Save(List<Member> members)
        {
            TransactionContext tc = null;

            try
            {
                tc = TransactionContext.Begin(true);
                foreach (Member member in members)
                {
                    if (member.IsNew)
                    {
                        int id = tc.GenerateID("Member", "MemberID");
                        base.SetObjectID(member, (id));
                        MemberDA.Insert(tc, member);
                    }
                    else
                    {
                        member.ModifiedBy = member.ModifiedBy;
                        member.ModifiedDate = DateTime.Now; //.GetServerDate().Date;
                        MemberDA.Update(tc, member);
                    }
                }

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

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

                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        public void UpdateMonthlyPension(List<Member> members)
        {
            TransactionContext tc = null;

            try
            {
                tc = TransactionContext.Begin(true);
                foreach (Member member in members)
                {
                    member.ModifiedBy = member.ModifiedBy;
                    member.ModifiedDate = DateTime.Now; //.GetServerDate().Date;
                    MemberDA.UpdateMonthlyPension(tc, member);
                }

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

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

                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        #endregion

        public void UpdateSettlement(TransactionContext tc, Member member)
        {
            try
            {
                if (!member.IsNew)
                {
                    member.ModifiedBy = member.ModifiedBy;
                    member.ModifiedDate = DateTime.Now;
                    MemberDA.UpdateSettlement(tc, member);
                }
            }
            catch (Exception e)
            {
                #region Handle Exception

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

                throw new ServiceException(e.Message, e);

                #endregion
            }
        }

        public DataTable GetTable(int fundtypeid)
        {
            DataTable dTbl = new DataTable("Member");
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                IDataReader ir = MemberDA.Get(tc, fundtypeid);
                dTbl.Load(ir);
                ir.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 dTbl;
        }

        public DataTable GetBalance()
        {
            DataTable dTbl = new DataTable("Member");
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                IDataReader ir = MemberDA.GetBalance(tc);
                dTbl.Load(ir);
                ir.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 dTbl;
        }

        public DataTable GetMembersMonthlyPension(int fundtypeid)
        {
            DataSet dSet = null;
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();
                dSet = MemberDA.GetMembersMonthlyPension(tc, fundtypeid);
                tc.End();
            }
            catch (Exception e)
            {
                #region Handle Exception

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

                throw new ServiceException(e.Message, e);

                #endregion
            }

            return dSet.Tables[0];
        }

        #region IMemberService Members

        public List<Member> Getmember(string sEmpID)
        {
            List<Member> Members = new List<Member>();
            TransactionContext tc = null;
            try
            {
                tc = TransactionContext.Begin();

                IDataReader dr = MemberDA.GetMember(tc, sEmpID);
                Members = CreateObjects(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 Members;
        }

        public Member Get(string empCode)
        {
            #region Cache Header

            Member member = new Member();
            TransactionContext tc = null;

            if (member != null)
                return member;

            #endregion

            try
            {
                tc = TransactionContext.Begin();
                DataReader dr = new DataReader(MemberDA.Get(tc, empCode));
                if (dr.Read())
                {
                    member = this.CreateObject<Member>(dr);
                }

                dr.Close();
                tc.End();
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }

            #region Cache Footer

            #endregion

            return member;
        }

        public Member Get(string empCode, string FMConn)
        {
            Member member = new Member();

            try
            {
                DataReader dr = new DataReader(MemberDA.Get(empCode, FMConn));
                if (dr.Read())
                {
                    member = this.CreateObject<Member>(dr);
                }

                dr.Close();
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }

            #region Cache Footer

            #endregion

            return member;
        }
        public List<Member> Get()
        {
            throw new NotImplementedException();
        }

        public List<Member> GetSettledMember(DateTime fromDate, DateTime toDate)
        {
            throw new NotImplementedException();
        }

        public List<Member> GetLiveMemberOn(DateTime liveOnDate)
        {
            throw new NotImplementedException();
        }

        public List<Member> GetAuditLiveMemberOn(DateTime YearEndLastDate, DateTime ActualAuditDate)
        {
            throw new NotImplementedException();
        }

        public DataTable GetTable()
        {
            throw new NotImplementedException();
        }

        public DataTable GetMembersMonthlyPension()
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}