using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Data.Entity;

using BLL.Base;
using BLL.Services.System;
using Model.Entities.Users;
using Model.UnitsOfWork;
using Model.ViewModel;
using Model.ViewModel.Edit;

namespace BLL.Services.Mapper
{
    public class GroupMapper : BaseServices
    {
        readonly PermissionServices permissionServices;

        public GroupMapper(UOW UOW, PermissionServices permissionServices) : base(UOW)
        {
            this.permissionServices = permissionServices;
        }


        /// <summary>
        /// DB -> Info
        /// Модель информации о группах
        /// </summary>
        /// <returns></returns>
        public List<InfoGroupModel> GetInfo_Group()
        {
            return UOW.Repo_Group.All_NoTrack_List.
                        Where(e => e.Name != EnumDefaultGroups.Анонимные.ToString()).
                        Select(e => new InfoGroupModel()
                        {
                            ID = e.ID,
                            Name = e.Name
                        }).ToList();
        }

        /// <summary>
        /// DB -> Edit
        /// Модель для редактирования групп
        /// </summary>
        /// <returns></returns>
        public List<EditGroupModel> GetEdit_Group()
        {
            var groups = UOW.Repo_Group.
                GetGroupWithDirectory(UOW.Repo_Group.All_List);

            return groups.Select(e => new EditGroupModel()
            {
                ID = e.ID,
                Name = e.Name,
                Changes = EnumChanges.NoChange,

                RootDirs = e.DirectoryPermissions.Permissions.
                    Select(e2 => new InfoRootDirModel()
                    {
                        ID = e2.Value.DirectoryID,
                        Name = e2.Value.RootDirectory.Name,

                        CanDownload = e2.Value.CanDownload,
                        CanOpen = e2.Value.CanOpen,
                        CanUpload = e2.Value.CanUpload
                    }).ToList()
            }).ToList();
        }

        /// <summary>
        /// Edit -> DB
        /// Преобразование Edit в db Entitites
        /// </summary>
        /// <param name="editGroup"></param>
        /// <returns></returns>
        public List<(EditGroupModel Edited, Group DB)> GetEntities_Group(List<EditGroupModel> editGroup)
        {
            List<(EditGroupModel Edited, Group DB)> res = new List<(EditGroupModel Edited, Group DB)>(editGroup.Count());
            var groups = UOW.Repo_Group.All_List;
            var root = UOW.Repo_SRootDirectory.All_List;

            foreach (var elem in editGroup)
            {
                //var current_groups_id = elem.Groups.
                //    Where(g => g.EnterInGroup).
                //    Select(g => g.ID);

                Group current_group = null;

                switch (elem.Changes)
                {
                    case EnumChanges.Create:
                        current_group = new Group() { Name = elem.Name };
                        elem.RootDirs.ForEach(e2 =>
                        {
                            if (root.FirstOrDefault(e => e.ID == e2.ID) != null)
                            {
                                current_group.DirectoryPermissions.AddOrUpdate(new Permission()
                                {
                                    CanUpload = e2.CanUpload,
                                    CanDownload = e2.CanDownload,
                                    CanOpen = e2.CanOpen,
                                    DirectoryID = e2.ID
                                });
                            }
                        });

                        break;
                    case EnumChanges.Update:
                        current_group = UOW.Repo_Group.All.
                            FirstOrDefault(e => e.ID == elem.ID);
                        current_group.Name = elem.Name;

                        elem.RootDirs.ForEach(e2 =>
                        {
                            if (root.FirstOrDefault(e => e.ID == e2.ID) != null)
                            {

                                current_group.DirectoryPermissions.AddOrUpdate(new Permission()
                                {
                                    CanUpload = e2.CanUpload,
                                    CanDownload = e2.CanDownload,
                                    CanOpen = e2.CanOpen,
                                    DirectoryID = e2.ID
                                });
                            }
                        });

                        break;
                    case EnumChanges.Delete:
                        current_group = UOW.Repo_Group.All.
                            FirstOrDefault(e => e.ID == elem.ID);
                        break;
                }

                res.Add(new ValueTuple<EditGroupModel, Group>(elem, current_group));
            }

            return res;
        }

    }
}
