using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;

namespace Valg.EVA.Skanning.JobManagement.Startup.Data
{
    public static class ClassExtensions
    {
        public static string PropertyName<T>(this Expression<Func<T>> expression)
        {
            var pex = expression.Body as MemberExpression;
            return pex.Member.Name;
        }

        public static string PropertyName<T1, T2>(this Expression<Func<T1, T2>> expression)
        {
            var pex = expression.Body as MemberExpression;
            if (pex == null)
            {
                var uex = expression.Body as UnaryExpression;
                if (uex == null)
                    return "";

                pex = uex.Operand as MemberExpression;
            }
            return pex.Member.Name;
        }

        public static void Update<TItem, TId>(
            this ObservableCollection<TItem> sourceCollection,
            IEnumerable<TItem> updatesCollection)
            where TItem : IUpdatable<TItem, TId>
        {
            var updatesList = updatesCollection
                .Cast<IUpdatable<TItem, TId>>()
                .ToList();

            var sourceList = sourceCollection
                .Cast<IUpdatable<TItem, TId>>()
                .ToList();

            var comparer = new UpdatableComparer<TItem, TId>();

            sourceList.Join(
                updatesList,
                a => a.Id,
                b => b.Id,
                (a,b) => new { Original = a, Updated = b })
                .ToList()
                .ForEach(g => g.Original.Update((TItem) g.Updated));

            sourceList
                .Except(updatesList, comparer)
                .ToList()
                .ForEach(pd => sourceCollection.Remove((TItem) pd));

            updatesList
                .Except(sourceList, comparer)
                .ToList()
                .ForEach(pd => sourceCollection.Add((TItem) pd));
        }

    }
}
