using System.Linq;

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

using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using System;

namespace BeWo.Service.DCEntityMapper
{
    public class UserDC_User : AbstractIDCEntityMapper<ApplicationUser, UserDC>
    {
        public override UserDC MergeWithDC(ApplicationUser pEntity, UserDC pDataContract)
        {
            pDataContract.UserOid = pEntity.Oid;
            pDataContract.UserVersion = pEntity.Version;
            pDataContract.LoginName = pEntity.LoginName;
            pDataContract.HashedPassword = pEntity.HashedPassword;
            pDataContract.RC2Password = pEntity.RC2EncryptedHash;
            pDataContract.Salt = pEntity.Salt;
	        pDataContract.Zeitstempel = pEntity.Zeitstempel ?? DateTime.Now;
		    

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

            pDataContract.UserGroups = MapperFactory.UserGroupDC_UserGroup.MapToNewDCs(pEntity.UserGroups);
            pDataContract.Settings = MapperFactory.SettingsDC_Settings.MapToNewDCs(pEntity.SettingList);
			pDataContract.ResetPasswordInfos = MapperFactory.ResetPasswordDC_ResetPassword.MapToNewDCs(pEntity.ResetPasswordInfos);

            return pDataContract;
        }

        public override ApplicationUser MergeWithEntity(UserDC pDataContract, ApplicationUser pEntity)
        {
            this.ConcurrencyCheck(pDataContract.UserVersion, pEntity);

            pEntity.Oid = pDataContract.UserOid;

            pEntity.Zeitstempel = pDataContract.Zeitstempel;

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

            pEntity.LoginName = pDataContract.LoginName;

            if (pDataContract.UserOid == null)
            {
                pEntity.ChangePassword(pDataContract.NewPassword);
            }
            pEntity.Salt = pDataContract.Salt;

            pEntity.UserGroups.RemoveRange(x => pDataContract.UserGroups.FirstOrDefault(y => x.Oid == y.UserGroupOid) == null);
            pEntity.UserGroups.AddRange(pDataContract.UserGroups.Where(x => pEntity.UserGroups.FirstOrDefault(y => x.UserGroupOid == y.Oid) == null).Select(dc => DAOFactory.GenericDAO.LoadByID<UserGroup>(dc.UserGroupOid.Value)));

            MapperFactory.SettingsDC_Settings.MergeWithEntitys(pDataContract.Settings, pEntity.SettingList);

			MapperFactory.ResetPasswordDC_ResetPassword.MergeWithEntitys(pDataContract.ResetPasswordInfos, pEntity.ResetPasswordInfos);

            return pEntity;
        }

        protected override bool AreDCAndEntityEqual(UserDC pDC, ApplicationUser pEntity)
        {
            if (pDC.UserOid == null)
            {
                return false;
            }

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