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

using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.ServiceContracts;

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

namespace BeWo.Service.ServiceImplementations
{
	[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
	public class ValueListServiceImp : IValueListService
	{
		public void DeactivateValueListEntries(Dictionary<long, long> pOid2Version)
		{
			try
			{
				ServiceLogic.SetActivationType<ValueListEntry>(pOid2Version, ActivationTypeId.Deleted);
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}
		}

		public void DeactivateValueListEntry(long pOid, long pVersion)
		{
			try
			{
				ServiceLogic.SetActivationType<ValueListEntry>(new Dictionary<long, long> { { pOid, pVersion } }, ActivationTypeId.Deleted);
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}

			throw new NotImplementedException();
		}

		public void DeleteValueListEntries(Dictionary<long, long> pOid2Version)
		{
			try
			{
				var lOriginals = DAOFactory.GenericDAO.LoadByIDs<ValueListEntry>(pOid2Version.Select(e => e.Key));
				lOriginals.DoForEach(or => MapperFactory.ValueListEntryDC_ValueListEntry.ConcurrencyCheck(pOid2Version[or.Oid.Value], or));

				DAOFactory.GenericDAO.Delete(lOriginals);
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}
		}

		public void DeleteValueListEntry(long pOid, long pVersion)
		{
			try
			{
				this.DeleteValueListEntries(new Dictionary<long, long> { { pOid, pVersion } });
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}
		}

		public ValueListEntryDC[] GetAllValueListEntrysByType(ValueListEntryType pType)
		{
			try
			{
				return MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDCs(DAOFactory.SearchDAO.FindValueListEntry(pType).Where(ve => ve.IsActive == ActivationTypeId.Active)).ToArray();
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}
		}

		public ValueListEntryDC[] GetAllValueListEntrysByTypes(List<ValueListEntryType> pTypes)
		{
			try
			{
				return MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDCs(DAOFactory.SearchDAO.FindValueListEntries(pTypes).Where(ve => ve.IsActive == ActivationTypeId.Active)).ToArray();
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}
		}

	    public ValueListEntryDC GetValueListEntryByOid(long pOid)
	    {
            try
            {
                return MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDC(DAOFactory.GenericDAO.LoadByID<ValueListEntry>(pOid));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
	    }

		public List<long> InsertNewValueListEntries(List<ValueListEntryDC> pEntries)
		{
			try
			{
				var lEntities = MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewEntities(pEntries);
				DAOFactory.GenericDAO.Insert(lEntities);
				return lEntities.Select(e => e.Oid.Value).ToList();
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}
		}

        public List<ValueListEntryDC> InsertAndLoadNewValueListEntries(IEnumerable<ValueListEntryDC> pEntries)
        {
            try
            {
                var lEntities = MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewEntities(pEntries);
                DAOFactory.GenericDAO.Insert(lEntities);
                return MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDCs(lEntities);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public ValueListEntryDC InsertNewValueListEntry(ValueListEntryDC pEntry)
	    {
	        try
	        {
                var lEntity = MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewEntity(pEntry);
                DAOFactory.GenericDAO.Insert(lEntity);
	            return MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDC(lEntity);
	        }
	        catch (Exception e)
	        {
                throw Utils.CreateBeWoFaultException(e);
	        }
	    }

		public void UpdateValueListEntries(List<ValueListEntryDC> pEntries)
		{
			try
			{
				var lOriginals = DAOFactory.GenericDAO.LoadByIDs<ValueListEntry>(pEntries.Select(en => en.ValueListEntryOid.Value));
				MapperFactory.ValueListEntryDC_ValueListEntry.MergeWithEntitys(pEntries, lOriginals);
				DAOFactory.GenericDAO.Update(lOriginals);
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}
		}

		public ValueListEntryDC[] GetAllValueListEntriesByOidForType(long pOid)
		{
			var original = DAOFactory.GenericDAO.GetByID<ValueListEntry>(pOid);

			return GetAllValueListEntrysByType(original.Type);
		}
	}
}