using System.Collections.Generic;
using System.Linq;

using BeWo.Data.Access;
using BeWo.Data.Entities;

using BS.Shared;
using BS.Shared.DataContracts;

namespace BeWo.Service.DCEntityMapper
{
    public class ServiceRecordDC_ServiceRecord : AbstractIDCEntityMapper<ServiceRecord, ServiceRecordDC>
    {
        public override ServiceRecordDC MergeWithDC(ServiceRecord pEntity, ServiceRecordDC pDataContract)
        {
            pDataContract.ServiceRecordOid = pEntity.Oid;
            pDataContract.ServiceRecordVersion = pEntity.Version;
            pDataContract.Start = pEntity.Start;
            pDataContract.End = pEntity.End;
            pDataContract.Notice = pEntity.Notice;
            pDataContract.Notice2 = pEntity.Notice2;
            pDataContract.Notice3 = pEntity.Notice3;
            pDataContract.Notice4 = pEntity.Notice4;
            pDataContract.Notice5 = pEntity.Notice5;
			pDataContract.DistanceInMeter = pEntity.DistanceInMeter;
			pDataContract.Relevance = pEntity.Relevance;
            pDataContract.SignatureOid = pEntity.SignatureOid;
            pDataContract.ServiceRecordType = pEntity.ServiceRecordType ?? ServiceRecordTypeId.DefaultActivity;

            if (pEntity.ServiceDescription != null)
            {
                pDataContract.ServiceDescription = MapperFactory.ServiceDescriptionDC_ServiceDescription.MapToNewDC(pEntity.ServiceDescription);
            }

            pDataContract.RoundedDuration = pEntity.RoundedDuration;
            pDataContract.InsertedOn = pEntity.InsTs;
            pDataContract.InsUser = pEntity.InsUser;
            pDataContract.WohnheimbuchungsOid = pEntity.WohnheimbuchungsOid;

            if (pEntity.Customer != null)
            {
                pDataContract.Customer = MapperFactory.CompactCustomerDC_Customer.MapToNewDC(pEntity.Customer);
            }

            if (pEntity.Employee != null)
            {
                pDataContract.Employee = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(pEntity.Employee);
            }

            if (pEntity.SupportConcept != null)
            {
                pDataContract.SupportConcept = MapperFactory.CompactSupportConceptDC_SupportConcept.MapToNewDC(pEntity.SupportConcept);
            }

            if (pEntity.CostBearer2SupportConcept != null)
            {
                pDataContract.CostBearer2SupportConceptOid = pEntity.CostBearer2SupportConcept.Oid.Value;
                if (pEntity.CostBearer2SupportConcept.CostBearer.Organisation != null)
                {
                    pDataContract.CostBearer = MapperFactory.CompactOrganisationDC_Organisation.MapToNewDC(pEntity.CostBearer2SupportConcept.CostBearer.Organisation);
                }
            }

            var list = new List<ValueListEntryType>();
			list.Add(ValueListEntryType.SupportConceptGoalType);
			list.Add(ValueListEntryType.SupportConceptGoalCategoryType);
			list.Add(ValueListEntryType.SupportConceptIndividualGoalCategoryType);
			list.Add(ValueListEntryType.SupportConceptIndividualGoalType);

            pDataContract.Goals = MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDCs(pEntity.ValueList.FindByTypes(list).Select(e2o => e2o.Entry));

            pDataContract.GroupEmployeeCount = pEntity.GroupEmployeeCount;
            pDataContract.GroupPersonCount = pEntity.GroupPersonCount;
            pDataContract.GroupRoundedDuration = pEntity.GroupRoundedDuration;
            pDataContract.GroupOid = pEntity.GroupOid;
	        pDataContract.IP = pEntity.IP;
			pDataContract.IsCreatedInMobileClient = pEntity.IsCreatedInMobileClient;

            return pDataContract;
        }

        public override ServiceRecord MergeWithEntity(ServiceRecordDC pDataContract, ServiceRecord pEntity)
        {
            ConcurrencyCheck(pDataContract.ServiceRecordVersion, pEntity);

            pEntity.Oid = pDataContract.ServiceRecordOid;
            pEntity.SignatureOid = pDataContract.SignatureOid;

            pEntity.Notice = pDataContract.Notice;
            pEntity.Notice2 = pDataContract.Notice2;
            pEntity.Notice3 = pDataContract.Notice3;
            pEntity.Notice4 = pDataContract.Notice4;
            pEntity.Notice5 = pDataContract.Notice5;
            pEntity.Start = pDataContract.Start;
            pEntity.End = pDataContract.End;
            pEntity.RoundedDuration = pDataContract.RoundedDuration;
			pEntity.DistanceInMeter = pDataContract.DistanceInMeter;
			pEntity.Relevance = pDataContract.Relevance;
            pEntity.WohnheimbuchungsOid = pDataContract.WohnheimbuchungsOid;
            pEntity.GroupEmployeeCount = pDataContract.GroupEmployeeCount;
            pEntity.GroupPersonCount = pDataContract.GroupPersonCount;
            pEntity.GroupRoundedDuration = pDataContract.GroupRoundedDuration;
            pEntity.ServiceRecordType = pDataContract.ServiceRecordType;

	        pEntity.IP = pDataContract.IP;

            if (pEntity.ServiceDescription == null || pEntity.ServiceDescription.Oid != pDataContract.ServiceDescription.ServiceDescriptionOid)
            {
                pEntity.ServiceDescription = DAOFactory.GenericDAO.LoadByID<ServiceDescription>(pDataContract.ServiceDescription.ServiceDescriptionOid.Value);
            }

            if (pEntity.Employee == null || pEntity.Employee.Oid != pDataContract.Employee.EmployeeOid)
            {
                pEntity.Employee = DAOFactory.GenericDAO.LoadByID<Employee>(pDataContract.Employee.EmployeeOid);
            }

            if (pDataContract.Customer == null)
            {
                pEntity.Customer = null;
            }
            else if (pEntity.Customer == null || pEntity.Customer.Oid != pDataContract.Customer.CustomerOid)
            {
                pEntity.Customer = DAOFactory.GenericDAO.LoadByID<Customer>(pDataContract.Customer.CustomerOid);
            }

            if (pDataContract.SupportConcept == null)
            {
                pEntity.SupportConcept = null;
            }
            else if (pEntity.SupportConcept == null || pEntity.SupportConcept.Oid != pDataContract.SupportConcept.SupportConceptOid)
            {
                pEntity.SupportConcept = DAOFactory.GenericDAO.LoadByID<SupportConcept>(pDataContract.SupportConcept.SupportConceptOid);
            }

            if (pDataContract.CostBearer == null)
            {
                pEntity.CostBearer2SupportConcept = null;
            }
            else if (pEntity.CostBearer2SupportConcept == null || pEntity.CostBearer2SupportConcept.CostBearer.Oid != pDataContract.CostBearer.CostBearerOid.Value)
            {
                pEntity.CostBearer2SupportConcept = pEntity.SupportConcept.CostBearer2SupportConceptList.Single(cb2sc => cb2sc.CostBearer.Oid == pDataContract.CostBearer.CostBearerOid);
            }
            else if (pEntity.CostBearer2SupportConceptOid != null && pDataContract.CostBearer2SupportConceptOid != null && pEntity.CostBearer2SupportConceptOid != pDataContract.CostBearer2SupportConceptOid)
            {
                pEntity.CostBearer2SupportConcept = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(pDataContract.CostBearer2SupportConceptOid.Value);
            }

            if (pDataContract.Goals == null)
            {
                pDataContract.Goals = new List<ValueListEntryDC>();
            }

			pEntity.IsCreatedInMobileClient = pDataContract.IsCreatedInMobileClient;

			var globalGoalCats =
					pDataContract.Goals.Where(g => g.Type == ValueListEntryType.SupportConceptGoalCategoryType).ToList();
            var globalGoals =
                    pDataContract.Goals.Where(g => g.Type == ValueListEntryType.SupportConceptGoalType).ToList();
			var individualGoalCats =
					pDataContract.Goals.Where(g => g.Type == ValueListEntryType.SupportConceptIndividualGoalCategoryType).ToList();
            var individualGoals =
                    pDataContract.Goals.Where(g => g.Type == ValueListEntryType.SupportConceptIndividualGoalType).ToList();

			MapperFactory.ValueListEntryDC_ValueListEntry.MapValueEntryListBack2Entity(globalGoalCats, pEntity.ValueList, ValueListEntryType.SupportConceptGoalCategoryType, TableID.ServiceRecord, false);

            //if (globalGoals.Count > 0)
				MapperFactory.ValueListEntryDC_ValueListEntry.MapValueEntryListBack2Entity(globalGoals, pEntity.ValueList, ValueListEntryType.SupportConceptGoalType, TableID.ServiceRecord, false);
				MapperFactory.ValueListEntryDC_ValueListEntry.MapValueEntryListBack2Entity(individualGoalCats, pEntity.ValueList, ValueListEntryType.SupportConceptIndividualGoalCategoryType, TableID.ServiceRecord, false);
			//if (individualGoals.Count > 0)
				MapperFactory.ValueListEntryDC_ValueListEntry.MapValueEntryListBack2Entity(individualGoals, pEntity.ValueList, ValueListEntryType.SupportConceptIndividualGoalType, TableID.ServiceRecord, false);

            return pEntity;
        }

        protected override bool AreDCAndEntityEqual(ServiceRecordDC pDC, ServiceRecord pEntity)
        {
            if (pDC.ServiceRecordOid == null)
            {
                return false;
            }

            return pDC.ServiceRecordOid == pEntity.Oid;
        }
    }
}