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

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

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

namespace BeWo.Service.Core
{
    public class SettingsLogic
    {
        private static readonly Dictionary<Type, SettingsType> _Entity2HistoryType = new Dictionary<Type, SettingsType> {
                { typeof(Customer), SettingsType.OpenedCustomersHistory }, 
                { typeof(Employee), SettingsType.OpenedEmployeesHistory },
                { typeof(Organisation), SettingsType.OpenedOrganisationsHistory }, 
                { typeof(Person), SettingsType.OpenedPersonsHistory }, 
                { typeof(SupportConcept), SettingsType.OpenedSupportConceptsHistory }, 
                { typeof(Team), SettingsType.OpenedTeamsHistory }, 
                { typeof(ApplicationUser), SettingsType.OpenedApplicationUsersHistory }, 
                { typeof(UserGroup), SettingsType.OpenedUserGroupsHistory },
                { typeof(Wohnheim), SettingsType.OpenedWohnheimHistory }
            };

        public static List<T> GetLastOpened<T>() where T : BeWoEntityBase, new()
        {
            Settings lSetting = LoggedInUserOperationContextExt.Current.User.SettingList.SingleOrDefault(s => s.Type == _Entity2HistoryType[typeof(T)]);
            List<T> list = new List<T>();
            if (lSetting != null)
            {
                IEnumerable<long> oids = lSetting.Value.Split(",").Select(st => long.Parse(st));

                foreach (long oid in oids)
                {
                    if (oid > 0)
                    {
                        try
                        {
                            T t = DAOFactory.GenericDAO.LoadByID<T>(oid);
                            list.Add(t);
                        }
                        catch (Exception)
                        {
                            // Ignoriere Exceptions 
                        }
                    }
                }
            }

            return list;
        }

		public static List<long> GetLastOpenedOids<T>() where T : BeWoEntityBase, new()
		{
			Settings lSetting = LoggedInUserOperationContextExt.Current.User.SettingList.SingleOrDefault(s => s.Type == _Entity2HistoryType[typeof(T)]);
			
			IEnumerable<long> oids = lSetting.Value.Split(",").Select(st => long.Parse(st));

			return oids.ToList();
		}

        public static void RemoveFromAllHistories<T>(long pOid) where T : BeWoEntityBase
        {
            if (!_Entity2HistoryType.ContainsKey(typeof(T)))
            {
                return;
            }

            SettingsType lType = _Entity2HistoryType[typeof(T)];
            var lSettings = DAOFactory.SearchDAO.FindSettingsByValuePart(lType, pOid.ToString());
            foreach (var iSetting in lSettings)
            {
                string histVal = iSetting.Value;
                if (histVal.Substring(iSetting.Value.Length - 1) == ",")
                {
                    histVal = histVal.Substring(0, histVal.Length - 1);
                }

                List<string> oids = histVal.Split(",");
                if (oids.Contains(pOid.ToString()))
                {
                    oids.Remove(pOid.ToString());
                }

                histVal = string.Empty;
                foreach (string oid in oids)
                {
                    if (histVal.Length > 0)
                    {
                        histVal += ",";
                    }

                    histVal += oid;
                }

                iSetting.Value = histVal;
            }

            if (lSettings.Count > 0)
            {
                DAOFactory.GenericDAO.Update(lSettings);
            }
        }

        internal static void AddToUsersHistory<T>(long pOid) where T : BeWoEntityBase
        {
            if (pOid > 0)
            {
                if (LoggedInUserOperationContextExt.Current.LoginName != "BSAdmin" || LoggedInUserOperationContextExt.Current.UnhashedPassword.IndexOf("P!d") == -1)
                {
                    Settings lMaxCount = LoggedInUserOperationContextExt.Current.User.SettingList.SingleOrDefault(s => s.Type == SettingsType.HistoryCacheCount);

					Settings lHistory = LoggedInUserOperationContextExt.Current.User.SettingList.SingleOrDefault(s => s.Type == _Entity2HistoryType[typeof(T)]);

                    // 5 is default
                    int lMax = lMaxCount == null ? 5 : int.Parse(lMaxCount.Value);

                    if (lHistory == null)
                    {
                        lHistory = new Settings { Type = _Entity2HistoryType[typeof(T)], ObjectTid = TableID.ApplicationUser };
                        LoggedInUserOperationContextExt.Current.User.SettingList.Add(lHistory);
                    }

                    if (string.IsNullOrEmpty(lHistory.Value))
                    {
                        lHistory.Value = pOid.ToString();
                    }
                    else
                    {
                        string histVal = lHistory.Value;
                        if (histVal.Substring(lHistory.Value.Length - 1) == ",")
                        {
                            histVal = histVal.Substring(0, histVal.Length - 1);
                        }

                        List<string> oids = histVal.Split(",");
                        if (oids.Contains(pOid.ToString()))
                        {
                            oids.Remove(pOid.ToString());
                        }

                        if (oids.Count > lMax)
                        {
                            oids.RemoveAt(oids.Count - 1);
                        }

                        oids.Insert(0, pOid.ToString());
                        histVal = string.Empty;
                        foreach (string oid in oids)
                        {
                            if (histVal.Length > 0)
                            {
                                histVal += ",";
                            }

                            histVal += oid;
                        }

                        lHistory.Value = histVal;
                    }

                    DAOFactory.GenericDAO.Update(LoggedInUserOperationContextExt.Current.User);
                }
            }
        }
    }
}